Emit the module exec function. If we are compiling just one module, this will be the normal C API exec function. If we are compiling 2+ modules, we generate a shared library for the modules and shims that call into the shared library, and in this case the shared modu
(
self, emitter: Emitter, module_name: str, module_prefix: str, module: ModuleIR
)
| 1222 | emitter.emit_line(error_stmt) |
| 1223 | |
| 1224 | def emit_module_exec_func( |
| 1225 | self, emitter: Emitter, module_name: str, module_prefix: str, module: ModuleIR |
| 1226 | ) -> None: |
| 1227 | """Emit the module exec function. |
| 1228 | |
| 1229 | If we are compiling just one module, this will be the normal C API |
| 1230 | exec function. If we are compiling 2+ modules, we generate a shared |
| 1231 | library for the modules and shims that call into the shared |
| 1232 | library, and in this case the shared module defines an internal |
| 1233 | exec function for each module and these will be called by the shims |
| 1234 | via Capsules. |
| 1235 | """ |
| 1236 | exec_name = f"CPyExec_{exported_name(module_name)}" |
| 1237 | declaration = f"int {exec_name}(PyObject *module)" |
| 1238 | emitter.context.declarations[exec_name] = HeaderDeclaration(declaration + ";") |
| 1239 | module_static = self.module_internal_static_name(module_name, emitter) |
| 1240 | emitter.emit_lines(declaration, "{") |
| 1241 | emitter.emit_line("intern_strings();") |
| 1242 | if self.compiler_options.depends_on_librt_internal: |
| 1243 | emitter.emit_line("if (import_librt_internal() < 0) {") |
| 1244 | emitter.emit_line("return -1;") |
| 1245 | emitter.emit_line("}") |
| 1246 | if LIBRT_BASE64 in module.dependencies: |
| 1247 | emitter.emit_line("if (import_librt_base64() < 0) {") |
| 1248 | emitter.emit_line("return -1;") |
| 1249 | emitter.emit_line("}") |
| 1250 | if LIBRT_STRINGS in module.dependencies: |
| 1251 | emitter.emit_line("if (import_librt_strings() < 0) {") |
| 1252 | emitter.emit_line("return -1;") |
| 1253 | emitter.emit_line("}") |
| 1254 | if LIBRT_TIME in module.dependencies: |
| 1255 | emitter.emit_line("if (import_librt_time() < 0) {") |
| 1256 | emitter.emit_line("return -1;") |
| 1257 | emitter.emit_line("}") |
| 1258 | if LIBRT_VECS in module.dependencies: |
| 1259 | emitter.emit_line("if (import_librt_vecs() < 0) {") |
| 1260 | emitter.emit_line("return -1;") |
| 1261 | emitter.emit_line("}") |
| 1262 | if LIBRT_RANDOM in module.dependencies: |
| 1263 | emitter.emit_line("if (import_librt_random() < 0) {") |
| 1264 | emitter.emit_line("return -1;") |
| 1265 | emitter.emit_line("}") |
| 1266 | emitter.emit_line("PyObject* modname = NULL;") |
| 1267 | if self.multi_phase_init: |
| 1268 | emitter.emit_line(f"{module_static} = module;") |
| 1269 | emitter.emit_line( |
| 1270 | f'modname = PyObject_GetAttrString((PyObject *){module_static}, "__name__");' |
| 1271 | ) |
| 1272 | |
| 1273 | module_globals = emitter.static_name("globals", module_name) |
| 1274 | emitter.emit_lines( |
| 1275 | f"{module_globals} = PyModule_GetDict({module_static});", |
| 1276 | f"if (unlikely({module_globals} == NULL))", |
| 1277 | " goto fail;", |
| 1278 | ) |
| 1279 | |
| 1280 | if self.multi_phase_init: |
| 1281 | emitter.emit_lines( |
no test coverage detected