1#     Copyright 2021, Kay Hayen, mailto:kay.hayen@gmail.com
2#
3#     Part of "Nuitka", an optimizing Python compiler that is compatible and
4#     integrates with CPython, but also works on its own.
5#
6#     Licensed under the Apache License, Version 2.0 (the "License");
7#     you may not use this file except in compliance with the License.
8#     You may obtain a copy of the License at
9#
10#        http://www.apache.org/licenses/LICENSE-2.0
11#
12#     Unless required by applicable law or agreed to in writing, software
13#     distributed under the License is distributed on an "AS IS" BASIS,
14#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15#     See the License for the specific language governing permissions and
16#     limitations under the License.
17#
18""" Templates for the loading of embedded modules.
19
20"""
21
22
23template_metapath_loader_compiled_module_entry = """\
24{%(module_name)s, modulecode_%(module_identifier)s, 0, 0, %(flags)s},"""
25
26template_metapath_loader_shlib_module_entry = """\
27{%(module_name)s, NULL, 0, 0, %(flags)s},"""
28
29template_metapath_loader_bytecode_module_entry = """\
30{%(module_name)s, NULL, %(bytecode)s, %(size)d, %(flags)s},"""
31
32
33template_metapath_loader_body = r"""
34/* Code to register embedded modules for meta path based loading if any. */
35
36#include <Python.h>
37
38#include "nuitka/constants_blob.h"
39
40#include "nuitka/unfreezing.h"
41
42/* Type bool */
43#ifndef __cplusplus
44#include "stdbool.h"
45#endif
46
47#if %(bytecode_count)d > 0
48static unsigned char *bytecode_data[%(bytecode_count)d];
49#else
50static unsigned char **bytecode_data = NULL;
51#endif
52
53/* Table for lookup to find compiled or bytecode modules included in this
54 * binary or module, or put along this binary as extension modules. We do
55 * our own loading for each of these.
56 */
57%(metapath_module_decls)s
58
59static struct Nuitka_MetaPathBasedLoaderEntry meta_path_loader_entries[] = {
60%(metapath_loader_inittab)s
61    {NULL, NULL, 0, 0, 0}
62};
63
64static void _loadBytesCodesBlob()
65{
66    static bool init_done = false;
67
68    if (init_done == false) {
69        loadConstantsBlob((PyObject **)bytecode_data, ".bytecode");
70
71        init_done = true;
72    }
73}
74
75
76void setupMetaPathBasedLoader(void) {
77    static bool init_done = false;
78    if (init_done == false) {
79        _loadBytesCodesBlob();
80        registerMetaPathBasedUnfreezer(meta_path_loader_entries, bytecode_data);
81
82        init_done = true;
83    }
84
85
86}
87
88// This provides the frozen (compiled bytecode) files that are included if
89// any.
90
91// These modules should be loaded as bytecode. They may e.g. have to be loadable
92// during "Py_Initialize" already, or for irrelevance, they are only included
93// in this un-optimized form. These are not compiled by Nuitka, and therefore
94// are not accelerated at all, merely bundled with the binary or module, so
95// that CPython library can start out finding them.
96
97struct frozen_desc {
98    char const *name;
99    int index;
100    int size;
101};
102
103static struct frozen_desc _frozen_modules[] = {
104%(frozen_modules)s
105    {NULL, 0, 0}
106};
107
108
109void copyFrozenModulesTo(struct _frozen *destination) {
110    _loadBytesCodesBlob();
111
112    struct frozen_desc *current = _frozen_modules;
113
114    for (;;) {
115        destination->name = (char *)current->name;
116        destination->code = bytecode_data[current->index];
117        destination->size = current->size;
118
119        if (destination->name == NULL) break;
120
121        current += 1;
122        destination += 1;
123    };
124}
125
126"""
127
128from . import TemplateDebugWrapper  # isort:skip
129
130TemplateDebugWrapper.checkDebug(globals())
131