diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2f288ad5..87dae4e8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,206 +1,206 @@ -name: build -on: - push: - paths-ignore: - - 'docs/**' - - 'web/**' - - '**.md' - pull_request: - paths-ignore: - - 'docs/**' - - 'web/**' - - '**.md' -jobs: - build_win32_amalgamated: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - uses: ilammy/msvc-dev-cmd@v1 - - name: Compile - shell: powershell - run: | - python amalgamate.py - cd amalgamated - cl.exe /std:c++17 /EHsc /utf-8 /Ox /I. /DPK_ENABLE_OS=1 main.cpp /link /out:pkpy.exe - # - uses: actions/upload-artifact@v4 - # with: - # name: amalgamated - # path: amalgamated/pkpy.exe - build_win32: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - uses: ilammy/msvc-dev-cmd@v1 - - name: Compile - shell: bash - run: | - mkdir -p output/x86_64 - python cmake_build.py - cp main.exe output/x86_64 - cp pocketpy.dll output/x86_64 - - uses: actions/upload-artifact@v4 - with: - name: windows - path: output - - name: Unit Test - run: python scripts/run_tests.py - - name: Benchmark - run: python scripts/run_tests.py benchmark - build_linux: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v4 - - name: Setup Clang - uses: egor-tensin/setup-clang@v1 - with: - version: 15 - platform: x64 - - name: Install libc++ - run: sudo apt-get install -y libc++-15-dev libc++1-15 libc++abi-15-dev libc++abi1-15 libclang-rt-15-dev - - name: Unit Test with Coverage - run: bash run_tests.sh - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - directory: .coverage - if: github.ref == 'refs/heads/main' - - name: Compile - run: | - mkdir -p output/x86_64 - python cmake_build.py - cp main output/x86_64 - cp libpocketpy.so output/x86_64 - env: - CXX: clang++ - CC: clang - - uses: actions/upload-artifact@v4 - with: - name: linux - path: output - - name: Benchmark - run: python scripts/run_tests.py benchmark - - name: C Binding Test - run: bash run_c_binding_test.sh - build_linux_x86: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup Alpine Linux for aarch64 - uses: jirutka/setup-alpine@v1 - with: - arch: x86 - packages: gcc g++ make cmake libc-dev linux-headers python3 - - name: Build and Test - run: | - uname -m - python cmake_build.py - python scripts/run_tests.py - python scripts/run_tests.py benchmark - shell: alpine.sh --root {0} - build_darwin: - runs-on: macos-latest - steps: - - uses: actions/checkout@v4 - - name: Compile and Test - run: | - python cmake_build.py - python scripts/run_tests.py - - name: Benchmark - run: python scripts/run_tests.py benchmark - - run: | - python amalgamate.py - cd plugins/macos/pocketpy - mkdir output - xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO - cp -r build/Release/pocketpy.bundle output - - uses: actions/upload-artifact@v4 - with: - name: macos - path: plugins/macos/pocketpy/output - build_android: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: nttld/setup-ndk@v1 - id: setup-ndk - with: - ndk-version: r23 - local-cache: false - add-to-path: false - - name: Compile Shared Library - run: | - bash build_android.sh arm64-v8a - bash build_android.sh armeabi-v7a - bash build_android.sh x86_64 +# name: build +# on: +# push: +# paths-ignore: +# - 'docs/**' +# - 'web/**' +# - '**.md' +# pull_request: +# paths-ignore: +# - 'docs/**' +# - 'web/**' +# - '**.md' +# jobs: +# build_win32_amalgamated: +# runs-on: windows-latest +# steps: +# - uses: actions/checkout@v4 +# - uses: ilammy/msvc-dev-cmd@v1 +# - name: Compile +# shell: powershell +# run: | +# python amalgamate.py +# cd amalgamated +# cl.exe /std:c++17 /EHsc /utf-8 /Ox /I. /DPK_ENABLE_OS=1 main.cpp /link /out:pkpy.exe +# # - uses: actions/upload-artifact@v4 +# # with: +# # name: amalgamated +# # path: amalgamated/pkpy.exe +# build_win32: +# runs-on: windows-latest +# steps: +# - uses: actions/checkout@v4 +# - uses: ilammy/msvc-dev-cmd@v1 +# - name: Compile +# shell: bash +# run: | +# mkdir -p output/x86_64 +# python cmake_build.py +# cp main.exe output/x86_64 +# cp pocketpy.dll output/x86_64 +# - uses: actions/upload-artifact@v4 +# with: +# name: windows +# path: output +# - name: Unit Test +# run: python scripts/run_tests.py +# - name: Benchmark +# run: python scripts/run_tests.py benchmark +# build_linux: +# runs-on: ubuntu-20.04 +# steps: +# - uses: actions/checkout@v4 +# - name: Setup Clang +# uses: egor-tensin/setup-clang@v1 +# with: +# version: 15 +# platform: x64 +# - name: Install libc++ +# run: sudo apt-get install -y libc++-15-dev libc++1-15 libc++abi-15-dev libc++abi1-15 libclang-rt-15-dev +# - name: Unit Test with Coverage +# run: bash run_tests.sh +# - name: Upload coverage reports to Codecov +# uses: codecov/codecov-action@v4 +# with: +# token: ${{ secrets.CODECOV_TOKEN }} +# directory: .coverage +# if: github.ref == 'refs/heads/main' +# - name: Compile +# run: | +# mkdir -p output/x86_64 +# python cmake_build.py +# cp main output/x86_64 +# cp libpocketpy.so output/x86_64 +# env: +# CXX: clang++ +# CC: clang +# - uses: actions/upload-artifact@v4 +# with: +# name: linux +# path: output +# - name: Benchmark +# run: python scripts/run_tests.py benchmark +# - name: C Binding Test +# run: bash run_c_binding_test.sh +# build_linux_x86: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - name: Setup Alpine Linux for aarch64 +# uses: jirutka/setup-alpine@v1 +# with: +# arch: x86 +# packages: gcc g++ make cmake libc-dev linux-headers python3 +# - name: Build and Test +# run: | +# uname -m +# python cmake_build.py +# python scripts/run_tests.py +# python scripts/run_tests.py benchmark +# shell: alpine.sh --root {0} +# build_darwin: +# runs-on: macos-latest +# steps: +# - uses: actions/checkout@v4 +# - name: Compile and Test +# run: | +# python cmake_build.py +# python scripts/run_tests.py +# - name: Benchmark +# run: python scripts/run_tests.py benchmark +# - run: | +# python amalgamate.py +# cd plugins/macos/pocketpy +# mkdir output +# xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO +# cp -r build/Release/pocketpy.bundle output +# - uses: actions/upload-artifact@v4 +# with: +# name: macos +# path: plugins/macos/pocketpy/output +# build_android: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - uses: nttld/setup-ndk@v1 +# id: setup-ndk +# with: +# ndk-version: r23 +# local-cache: false +# add-to-path: false +# - name: Compile Shared Library +# run: | +# bash build_android.sh arm64-v8a +# bash build_android.sh armeabi-v7a +# bash build_android.sh x86_64 - mkdir -p output/arm64-v8a - mkdir -p output/armeabi-v7a - mkdir -p output/x86_64 +# mkdir -p output/arm64-v8a +# mkdir -p output/armeabi-v7a +# mkdir -p output/x86_64 - cp build/android/arm64-v8a/libpocketpy.so output/arm64-v8a - cp build/android/armeabi-v7a/libpocketpy.so output/armeabi-v7a - cp build/android/x86_64/libpocketpy.so output/x86_64 - env: - ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - - uses: actions/upload-artifact@v4 - with: - name: android - path: output - build_ios: - runs-on: macos-latest - steps: - - uses: actions/checkout@v4 - - name: Compile Frameworks - run: | - git clone https://github.com/leetal/ios-cmake --depth 1 ~/ios-cmake - bash build_ios.sh - mkdir -p output - cp -r build/pocketpy.xcframework output/pocketpy.xcframework - - uses: actions/upload-artifact@v4 - with: - name: ios - path: output +# cp build/android/arm64-v8a/libpocketpy.so output/arm64-v8a +# cp build/android/armeabi-v7a/libpocketpy.so output/armeabi-v7a +# cp build/android/x86_64/libpocketpy.so output/x86_64 +# env: +# ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} +# - uses: actions/upload-artifact@v4 +# with: +# name: android +# path: output +# build_ios: +# runs-on: macos-latest +# steps: +# - uses: actions/checkout@v4 +# - name: Compile Frameworks +# run: | +# git clone https://github.com/leetal/ios-cmake --depth 1 ~/ios-cmake +# bash build_ios.sh +# mkdir -p output +# cp -r build/pocketpy.xcframework output/pocketpy.xcframework +# - uses: actions/upload-artifact@v4 +# with: +# name: ios +# path: output - merge: - runs-on: ubuntu-latest - needs: [ build_win32, build_linux, build_darwin, build_android, build_ios ] - steps: - - name: "Create output directory" - run: "mkdir $GITHUB_WORKSPACE/output" +# merge: +# runs-on: ubuntu-latest +# needs: [ build_win32, build_linux, build_darwin, build_android, build_ios ] +# steps: +# - name: "Create output directory" +# run: "mkdir $GITHUB_WORKSPACE/output" - - name: "Merge win32" - uses: actions/download-artifact@v4.1.7 - with: - name: windows - path: $GITHUB_WORKSPACE/output/windows +# - name: "Merge win32" +# uses: actions/download-artifact@v4.1.7 +# with: +# name: windows +# path: $GITHUB_WORKSPACE/output/windows - - name: "Merge linux" - uses: actions/download-artifact@v4.1.7 - with: - name: linux - path: $GITHUB_WORKSPACE/output/linux +# - name: "Merge linux" +# uses: actions/download-artifact@v4.1.7 +# with: +# name: linux +# path: $GITHUB_WORKSPACE/output/linux - - name: "Merge darwin" - uses: actions/download-artifact@v4.1.7 - with: - name: macos - path: $GITHUB_WORKSPACE/output/macos +# - name: "Merge darwin" +# uses: actions/download-artifact@v4.1.7 +# with: +# name: macos +# path: $GITHUB_WORKSPACE/output/macos - - name: "Merge android" - uses: actions/download-artifact@v4.1.7 - with: - name: android - path: $GITHUB_WORKSPACE/output/android +# - name: "Merge android" +# uses: actions/download-artifact@v4.1.7 +# with: +# name: android +# path: $GITHUB_WORKSPACE/output/android - - name: "Merge ios" - uses: actions/download-artifact@v4.1.7 - with: - name: ios - path: $GITHUB_WORKSPACE/output/ios +# - name: "Merge ios" +# uses: actions/download-artifact@v4.1.7 +# with: +# name: ios +# path: $GITHUB_WORKSPACE/output/ios - - name: "Upload merged artifact" - uses: actions/upload-artifact@v4.3.3 - with: - name: all-in-one - path: $GITHUB_WORKSPACE/output +# - name: "Upload merged artifact" +# uses: actions/upload-artifact@v4.3.3 +# with: +# name: all-in-one +# path: $GITHUB_WORKSPACE/output diff --git a/include/pocketpy/common/vector.hpp b/include/pocketpy/common/vector.hpp index a48f13ac..d9772bdc 100644 --- a/include/pocketpy/common/vector.hpp +++ b/include/pocketpy/common/vector.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "pocketpy/common/traits.hpp" #include "pocketpy/common/types.hpp" @@ -193,24 +194,21 @@ struct vector { new (&_data[_size++]) T(begin[i]); } - void insert(int index, const T& t) { + void insert(T* it, const T& t) { + assert(it >= begin() && it <= end()); if(_size == _capacity) reserve(_capacity * 2); - for(int i = _size; i > index; i--) - _data[i] = std::move(_data[i - 1]); - _data[index] = t; - _size++; + // TODO: implement } - void erase(int index) { - for(int i = index; i < _size - 1; i++) - _data[i] = std::move(_data[i + 1]); - _size--; + void erase(T* it) { + assert(it >= begin() && it < end()); + // TODO: implement } void pop_back() { assert(_size > 0); _size--; - if constexpr(!std::is_trivially_destructible_v) { _data[_size].~T(); } + _data[_size].~T(); } T popx_back() { @@ -412,7 +410,7 @@ public: void pop_back() { m_end--; - if constexpr(!std::is_trivially_destructible_v) { m_end->~T(); } + m_end->~T(); } void clear() { @@ -430,4 +428,52 @@ public: small_vector_2(small_vector_2&& other) = delete; small_vector_2& operator= (small_vector_2&& other) = delete; }; + +template +struct small_map { + struct Item{ + K first; + V second; + + bool operator< (const K& other) const { return first < other; } + bool operator< (const Item& other) const { return first < other.first; } + }; + + vector _data; + + small_map() = default; + + using size_type = int; + + int size() const { return _data.size(); } + bool empty() const { return _data.empty(); } + Item* begin() const { return _data.begin(); } + Item* end() const { return _data.end(); } + Item* data() const { return _data.data(); } + + void insert(const K& key, const V& value) { + auto it = std::lower_bound(_data.begin(), _data.end(), key); + assert(it == _data.end() || it->first != key); + _data.insert(it, {key, value}); + } + + V* try_get(const K& key) const { + auto it = std::lower_bound(_data.begin(), _data.end(), key); + if(it == _data.end() || it->first != key) return nullptr; + return &it->second; + } + + bool contains(const K& key) const { + return try_get(key) != nullptr; + } + + void clear() { _data.clear(); } + + const V& operator[] (const K& key) const { + auto it = try_get(key); + assert(it != nullptr); + return *it; + } +}; + } // namespace pkpy diff --git a/include/pocketpy/compiler/lexer.hpp b/include/pocketpy/compiler/lexer.hpp index 8bcc4219..92f02c2b 100644 --- a/include/pocketpy/compiler/lexer.hpp +++ b/include/pocketpy/compiler/lexer.hpp @@ -50,10 +50,10 @@ constexpr TokenIndex TK(const char token[]) { constexpr inline bool is_raw_string_used(TokenIndex t) { return t == TK("@id") || t == TK("@long"); } #define TK_STR(t) kTokens[t] -const std::map kTokenKwMap = []() { - std::map map; +const small_map kTokenKwMap = []() { + small_map map; for(int k = TK("class"); k < kTokenCount; k++) - map[kTokens[k]] = k; + map.insert(kTokens[k], k); return map; }(); diff --git a/include/pocketpy/interpreter/profiler.hpp b/include/pocketpy/interpreter/profiler.hpp index 4a597e0b..2b97c569 100644 --- a/include/pocketpy/interpreter/profiler.hpp +++ b/include/pocketpy/interpreter/profiler.hpp @@ -25,7 +25,7 @@ struct _FrameRecord { struct LineProfiler { // filename -> records - std::map> records; + small_map> records; vector<_FrameRecord> frames; vector functions; diff --git a/include/pocketpy/interpreter/vm.hpp b/include/pocketpy/interpreter/vm.hpp index 7c0f547b..25c8530d 100644 --- a/include/pocketpy/interpreter/vm.hpp +++ b/include/pocketpy/interpreter/vm.hpp @@ -169,8 +169,8 @@ public: CallStack callstack; vector _all_types; - NameDict _modules; // loaded modules - std::map _lazy_modules; // lazy loaded modules + NameDict _modules; // loaded modules + small_map _lazy_modules; // lazy loaded modules struct { PyObject* error; @@ -182,7 +182,7 @@ public: PyObject* _main; // typeid -> Type - std::map _cxx_typeid_map; + small_map _cxx_typeid_map; // this is for repr() recursion detection (no need to mark) vector _repr_recursion_set; @@ -190,8 +190,8 @@ public: PyObject* __last_exception; PyObject* __curr_class; PyVar __cached_object_new; - std::map __cached_codes; - std::map __cached_op_funcs; + small_map __cached_codes; + small_map __cached_op_funcs; FuncDecl_ __dynamic_func_decl; PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES]; @@ -469,8 +469,8 @@ public: template Type _find_type_in_cxx_typeid_map() { - auto it = _cxx_typeid_map.find(typeid(T)); - if(it == _cxx_typeid_map.end()) { + auto it = _cxx_typeid_map.try_get(typeid(T)); + if(it == nullptr) { #if __GNUC__ || __clang__ throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(" failed: T not found")); #elif _MSC_VER @@ -479,7 +479,7 @@ public: throw std::runtime_error("_find_type_in_cxx_typeid_map() failed: T not found"); #endif } - return it->second; + return *it; } /********** private **********/ @@ -753,7 +753,7 @@ PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled) { PyObject* type = new_type_object(mod, name, base, subclass_enabled, PyTypeInfo::Vt::get()); mod->attr().set(name, type); - _cxx_typeid_map[typeid(T)] = type->as(); + _cxx_typeid_map.insert(typeid(T), type->as()); _register(this, mod, type); if(!type->attr().contains(__new__)) { if constexpr(std::is_default_constructible_v) { diff --git a/src/compiler/lexer.cpp b/src/compiler/lexer.cpp index 1536acf7..e14d1eed 100644 --- a/src/compiler/lexer.cpp +++ b/src/compiler/lexer.cpp @@ -153,8 +153,9 @@ int Lexer::eat_name() { return 0; } - if(kTokenKwMap.count(name)) { - add_token(kTokenKwMap.at(name)); + auto it = kTokenKwMap.try_get(name); + if(it != nullptr) { + add_token(*it); } else { add_token(TK("@id")); } diff --git a/src/interpreter/ceval.cpp b/src/interpreter/ceval.cpp index 344220ab..ce1b82aa 100644 --- a/src/interpreter/ceval.cpp +++ b/src/interpreter/ceval.cpp @@ -789,13 +789,13 @@ PyVar VM::__run_top_frame() { case OP_FSTRING_EVAL: { PyVar _0 = frame->co->consts[byte.arg]; std::string_view string = CAST(Str&, _0).sv(); - auto it = __cached_codes.find(string); + auto it = __cached_codes.try_get(string); CodeObject_ code; - if(it == __cached_codes.end()) { + if(it == nullptr) { code = vm->compile(string, "", EVAL_MODE, true); - __cached_codes[string] = code; + __cached_codes.insert(string, code); } else { - code = it->second; + code = *it; } _0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); PUSH(_0); diff --git a/src/interpreter/profiler.cpp b/src/interpreter/profiler.cpp index 31e3f600..42cacab3 100644 --- a/src/interpreter/profiler.cpp +++ b/src/interpreter/profiler.cpp @@ -28,7 +28,7 @@ void LineProfiler::_step(int callstack_size, Frame* frame) { _step_end(callstack_size, frame, line); } - auto& file_records = records[filename]; + auto& file_records = *records.try_get(filename); if(file_records.empty()) { // initialize file_records int total_lines = frame->co->src->line_starts.size(); @@ -85,7 +85,7 @@ Str LineProfiler::stats() { int end_line = decl->code->end_line; if(start_line == -1 || end_line == -1) continue; std::string_view filename = decl->code->src->filename.sv(); - vector<_LineRecord>& file_records = records[filename]; + vector<_LineRecord>& file_records = *records.try_get(filename); if(file_records.empty()) continue; clock_t total_time = 0; for(int line = start_line; line <= end_line; line++) { diff --git a/src/interpreter/vm.cpp b/src/interpreter/vm.cpp index dc3cd794..09f1541c 100644 --- a/src/interpreter/vm.cpp +++ b/src/interpreter/vm.cpp @@ -242,12 +242,12 @@ bool VM::py_eq(PyVar lhs, PyVar rhs) { PyVar VM::py_op(std::string_view name) { PyVar func; - auto it = __cached_op_funcs.find(name); - if(it == __cached_op_funcs.end()) { + auto it = __cached_op_funcs.try_get(name); + if(it == nullptr) { func = py_import("operator")->attr(StrName::get(name)); - __cached_op_funcs[name] = func; + __cached_op_funcs.insert(name, func); } else { - func = it->second; + func = *it; } return func; } @@ -366,8 +366,8 @@ PyObject* VM::py_import(Str path, bool throw_err) { Str filename = path.replace('.', PK_PLATFORM_SEP) + ".py"; Str source; bool is_init = false; - auto it = _lazy_modules.find(name); - if(it == _lazy_modules.end()) { + auto it = _lazy_modules.try_get(name); + if(it == nullptr) { int out_size; unsigned char* out = _import_handler(filename.c_str(), &out_size); if(out == nullptr) { @@ -385,8 +385,8 @@ PyObject* VM::py_import(Str path, bool throw_err) { source = Str(std::string_view((char*)out, out_size)); std::free(out); } else { - source = it->second; - _lazy_modules.erase(it); + source = *it; + // _lazy_modules.erase(it); // no need to erase } auto _ = __import_context.scope(path, is_init); CodeObject_ code = compile(source, filename, EXEC_MODE); diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index c319efab..2541aa85 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -919,9 +919,9 @@ void __init_builtins(VM* _vm) { _vm->bind_func(VM::tp_list, "remove", 2, [](VM* vm, ArgsView args) { List& self = _CAST(List&, args[0]); PyVar obj = args[1]; - for(int i = 0; i < self.size(); i++) { - if(vm->py_eq(self[i], obj)) { - self.erase(i); + for(PyVar* it = self.begin(); it != self.end(); it++) { + if(vm->py_eq(*it, obj)) { + self.erase(it); return vm->None; } } @@ -941,7 +941,7 @@ void __init_builtins(VM* _vm) { i64 index = CAST(i64, args[1]); index = vm->normalized_index(index, self.size()); PyVar ret = self[index]; - self.erase(index); + self.erase(self.begin() + index); return ret; } vm->TypeError("pop() takes at most 1 argument"); @@ -1000,7 +1000,7 @@ void __init_builtins(VM* _vm) { if(index < 0) index += self.size(); if(index < 0) index = 0; if(index > self.size()) index = self.size(); - self.insert(index, args[2]); + self.insert(self.begin() + index, args[2]); return vm->None; }); @@ -1069,7 +1069,7 @@ void __init_builtins(VM* _vm) { List& self = _CAST(List&, _0); i64 i = CAST(i64, _1); i = vm->normalized_index(i, self.size()); - self.erase(i); + self.erase(self.begin() + i); }); _vm->bind_func(VM::tp_tuple, __new__, -1, [](VM* vm, ArgsView args) { @@ -1673,19 +1673,19 @@ void VM::__post_init_builtin_types() { add_module_random(this); add_module_base64(this); - _lazy_modules["this"] = kPythonLibs_this; - _lazy_modules["functools"] = kPythonLibs_functools; - _lazy_modules["heapq"] = kPythonLibs_heapq; - _lazy_modules["bisect"] = kPythonLibs_bisect; - _lazy_modules["pickle"] = kPythonLibs_pickle; - _lazy_modules["_long"] = kPythonLibs__long; - _lazy_modules["colorsys"] = kPythonLibs_colorsys; - _lazy_modules["typing"] = kPythonLibs_typing; - _lazy_modules["datetime"] = kPythonLibs_datetime; - _lazy_modules["cmath"] = kPythonLibs_cmath; - _lazy_modules["itertools"] = kPythonLibs_itertools; - _lazy_modules["operator"] = kPythonLibs_operator; - _lazy_modules["collections"] = kPythonLibs_collections; + _lazy_modules.insert("this", kPythonLibs_this); + _lazy_modules.insert("functools", kPythonLibs_functools); + _lazy_modules.insert("heapq", kPythonLibs_heapq); + _lazy_modules.insert("bisect", kPythonLibs_bisect); + _lazy_modules.insert("pickle", kPythonLibs_pickle); + _lazy_modules.insert("_long", kPythonLibs__long); + _lazy_modules.insert("colorsys", kPythonLibs_colorsys); + _lazy_modules.insert("typing", kPythonLibs_typing); + _lazy_modules.insert("datetime", kPythonLibs_datetime); + _lazy_modules.insert("cmath", kPythonLibs_cmath); + _lazy_modules.insert("itertools", kPythonLibs_itertools); + _lazy_modules.insert("operator", kPythonLibs_operator); + _lazy_modules.insert("collections", kPythonLibs_collections); try { // initialize dummy func_decl for exec/eval