/
_pyodide_core.c
102 lines (89 loc) · 3.57 KB
/
_pyodide_core.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "hiwire.h"
#include "python2js.h"
#include <emscripten.h>
#include <stdbool.h>
#define FATAL_ERROR(args...) \
do { \
PyErr_Format(PyExc_ImportError, args); \
FAIL(); \
} while (0)
#define FAIL_IF_STATUS_EXCEPTION(status) \
if (PyStatus_Exception(status)) { \
goto finally; \
}
#define TRY_INIT(mod) \
do { \
int mod##_init(); \
if (mod##_init()) { \
FATAL_ERROR("Failed to initialize module %s.", #mod); \
} \
} while (0)
#define TRY_INIT_WITH_CORE_MODULE(mod) \
do { \
int mod##_init(PyObject* mod); \
if (mod##_init(core_module)) { \
FATAL_ERROR("Failed to initialize module %s.", #mod); \
} \
} while (0)
static struct PyModuleDef core_module_def = {
PyModuleDef_HEAD_INIT,
.m_name = "_pyodide_core",
.m_doc = "Pyodide C builtins",
.m_size = -1,
};
PyObject*
PyInit__pyodide_core(void)
{
EM_ASM({
// Emscripten doesn't make UTF8ToString or wasmTable available on Module by
// default...
Module.UTF8ToString = UTF8ToString;
Module.wasmTable = wasmTable;
// Emscripten has a bug where it accidentally exposes an empty object as
// Module.ERRNO_CODES
Module.ERRNO_CODES = ERRNO_CODES;
// sourmash needs open64 to mean the same thing as open.
// Emscripten 3.1.44 seems to have removed it??
wasmImports["open64"] = wasmImports["open"];
});
bool success = false;
PyObject* _pyodide = NULL;
PyObject* core_module = NULL;
JsRef _pyodide_proxy = NULL;
_pyodide = PyImport_ImportModule("_pyodide");
if (_pyodide == NULL) {
FATAL_ERROR("Failed to import _pyodide module.");
}
core_module = PyModule_Create(&core_module_def);
if (core_module == NULL) {
FATAL_ERROR("Failed to create core module.");
}
TRY_INIT_WITH_CORE_MODULE(error_handling);
TRY_INIT(hiwire);
TRY_INIT(docstring);
TRY_INIT(js2python);
TRY_INIT_WITH_CORE_MODULE(python2js);
TRY_INIT(python2js_buffer);
TRY_INIT_WITH_CORE_MODULE(JsProxy);
TRY_INIT_WITH_CORE_MODULE(pyproxy);
PyObject* module_dict = PyImport_GetModuleDict(); /* borrowed */
if (PyDict_SetItemString(module_dict, "_pyodide_core", core_module)) {
FATAL_ERROR("Failed to add '_pyodide_core' module to modules dict.");
FAIL();
}
// Enable JavaScript access to the _pyodide module.
_pyodide_proxy = python2js(_pyodide);
if (_pyodide_proxy == NULL) {
FATAL_ERROR("Failed to create _pyodide proxy.");
}
EM_ASM({ API._pyodide = Hiwire.pop_value($0); }, _pyodide_proxy);
success = true;
finally:
Py_CLEAR(_pyodide);
if (!success) {
Py_CLEAR(core_module);
}
return core_module;
}