Generate the init function for a shared library. A shared library contains all the actual code for a compilation group. The init function is responsible for creating Capsules that wrap pointers to the initialization function of all the real init functions fo
(self, emitter: Emitter)
| 890 | code_emitter.emit_line("};") |
| 891 | |
| 892 | def generate_shared_lib_init(self, emitter: Emitter) -> None: |
| 893 | """Generate the init function for a shared library. |
| 894 | |
| 895 | A shared library contains all the actual code for a |
| 896 | compilation group. |
| 897 | |
| 898 | The init function is responsible for creating Capsules that |
| 899 | wrap pointers to the initialization function of all the real |
| 900 | init functions for modules in this shared library as well as |
| 901 | the export table containing all the exported functions and |
| 902 | values from all the modules. |
| 903 | |
| 904 | These capsules are stored in attributes of the shared library. |
| 905 | """ |
| 906 | assert self.group_name is not None |
| 907 | |
| 908 | emitter.emit_line() |
| 909 | |
| 910 | short_name = shared_lib_name(self.group_name).split(".")[-1] |
| 911 | |
| 912 | emitter.emit_lines( |
| 913 | f"static int exec_{short_name}(PyObject *module)", |
| 914 | "{", |
| 915 | "int res;", |
| 916 | "PyObject *capsule;", |
| 917 | "PyObject *tmp;", |
| 918 | "", |
| 919 | ) |
| 920 | |
| 921 | if self.compiler_options.separate: |
| 922 | emitter.emit_lines( |
| 923 | 'capsule = PyCapsule_New(&exports, "{}.exports", NULL);'.format( |
| 924 | shared_lib_name(self.group_name) |
| 925 | ), |
| 926 | "if (!capsule) {", |
| 927 | "goto fail;", |
| 928 | "}", |
| 929 | 'res = PyObject_SetAttrString(module, "exports", capsule);', |
| 930 | "Py_DECREF(capsule);", |
| 931 | "if (res < 0) {", |
| 932 | "goto fail;", |
| 933 | "}", |
| 934 | "", |
| 935 | # Expose ensure_deps_<short> as a capsule so the shim can call |
| 936 | # it before invoking the per-module init. |
| 937 | f"extern int ensure_deps_{short_name}(void);", |
| 938 | 'capsule = PyCapsule_New((void *)ensure_deps_{sh}, "{lib}.ensure_deps", NULL);'.format( |
| 939 | sh=short_name, lib=shared_lib_name(self.group_name) |
| 940 | ), |
| 941 | "if (!capsule) {", |
| 942 | "goto fail;", |
| 943 | "}", |
| 944 | 'res = PyObject_SetAttrString(module, "ensure_deps", capsule);', |
| 945 | "Py_DECREF(capsule);", |
| 946 | "if (res < 0) {", |
| 947 | "goto fail;", |
| 948 | "}", |
| 949 | "", |
no test coverage detected