Skip to content

Commit a5cd7d9

Browse files
committed
Add separate _api.c file for each librt module
1 parent edf9c52 commit a5cd7d9

28 files changed

Lines changed: 396 additions & 359 deletions

mypyc/build.py

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,11 @@ class ModDesc(NamedTuple):
5353

5454

5555
LIBRT_MODULES = [
56-
ModDesc(
57-
"librt.internal",
58-
["internal/librt_internal_static.c", "internal/librt_internal.c"],
59-
[],
60-
["internal"],
61-
),
62-
ModDesc(
63-
"librt.strings",
64-
["strings/librt_strings_static.c", "strings/librt_strings.c"],
65-
[],
66-
["strings"],
67-
),
56+
ModDesc("librt.internal", ["internal/librt_internal.c"], [], ["internal"]),
57+
ModDesc("librt.strings", ["strings/librt_strings.c"], [], ["strings"]),
6858
ModDesc(
6959
"librt.base64",
7060
[
71-
"base64/librt_base64_static.c",
7261
"base64/librt_base64.c",
7362
"base64/lib.c",
7463
"base64/codec_choose.c",
@@ -118,7 +107,6 @@ class ModDesc(NamedTuple):
118107
ModDesc(
119108
"librt.vecs",
120109
[
121-
"vecs/librt_vecs_static.c",
122110
"vecs/librt_vecs.c",
123111
"vecs/vec_i64.c",
124112
"vecs/vec_i32.c",
@@ -132,9 +120,7 @@ class ModDesc(NamedTuple):
132120
["vecs/librt_vecs.h", "vecs/vec_template.c"],
133121
["vecs"],
134122
),
135-
ModDesc(
136-
"librt.time", ["time/librt_time_static.c", "time/librt_time.c"], ["time/librt_time.h"], []
137-
),
123+
ModDesc("librt.time", ["time/librt_time.c"], ["time/librt_time.h"], []),
138124
]
139125

140126
try:
@@ -531,9 +517,7 @@ def mypyc_build(
531517
*,
532518
separate: bool | list[tuple[list[str], str | None]] = False,
533519
only_compile_paths: Iterable[str] | None = None,
534-
skip_cgen_input: (
535-
tuple[list[list[tuple[str, str]]], list[tuple[str, bool, list[str]]]] | None
536-
) = None,
520+
skip_cgen_input: tuple[list[list[tuple[str, str]]], list[tuple[str, list[str]]]] | None = None,
537521
always_use_shared_lib: bool = False,
538522
) -> tuple[emitmodule.Groups, list[tuple[list[str], list[str]]], list[SourceDep]]:
539523
"""Do the front and middle end of mypyc building, producing and writing out C source."""
@@ -567,10 +551,7 @@ def mypyc_build(
567551
write_file(os.path.join(compiler_options.target_dir, "ops.txt"), ops_text)
568552
else:
569553
group_cfiles = skip_cgen_input[0]
570-
source_deps = [
571-
SourceDep(path, has_header=hdr, include_dirs=dirs)
572-
for (path, hdr, dirs) in skip_cgen_input[1]
573-
]
554+
source_deps = [SourceDep(path, include_dirs=dirs) for (path, dirs) in skip_cgen_input[1]]
574555

575556
# Write out the generated C and collect the files for each group
576557
# Should this be here??
@@ -687,9 +668,7 @@ def mypycify(
687668
strip_asserts: bool = False,
688669
multi_file: bool = False,
689670
separate: bool | list[tuple[list[str], str | None]] = False,
690-
skip_cgen_input: (
691-
tuple[list[list[tuple[str, str]]], list[tuple[str, bool, list[str]]]] | None
692-
) = None,
671+
skip_cgen_input: tuple[list[list[tuple[str, str]]], list[tuple[str, list[str]]]] | None = None,
693672
target_dir: str | None = None,
694673
include_runtime_files: bool | None = None,
695674
strict_dunder_typing: bool = False,
@@ -812,8 +791,7 @@ def mypycify(
812791
files_to_copy = list(RUNTIME_C_FILES)
813792
for source_dep in source_deps:
814793
files_to_copy.append(source_dep.path)
815-
if header := source_dep.get_header():
816-
files_to_copy.append(header)
794+
files_to_copy.append(source_dep.get_header())
817795
include_dirs.update(source_dep.include_dirs)
818796

819797
# Copy all files

mypyc/codegen/emitmodule.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def collect_source_dependencies(modules: dict[str, ModuleIR]) -> set[SourceDep]:
444444
if isinstance(dep, SourceDep):
445445
source_deps.add(dep)
446446
else:
447-
source_deps.add(dep.static_data_dep())
447+
source_deps.add(dep.api_dep())
448448
return source_deps
449449

450450

@@ -588,7 +588,7 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]:
588588
for source_dep in sorted(source_deps, key=lambda d: d.path):
589589
base_emitter.emit_line(f'#include "{source_dep.path}"')
590590
if self.compiler_options.depends_on_librt_internal:
591-
base_emitter.emit_line("#include <internal/librt_internal_static.c>")
591+
base_emitter.emit_line("#include <internal/librt_internal_api.c>")
592592
base_emitter.emit_line(f'#include "__native{self.short_group_suffix}.h"')
593593
base_emitter.emit_line(f'#include "__native_internal{self.short_group_suffix}.h"')
594594
emitter = base_emitter
@@ -658,8 +658,7 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]:
658658
# Include headers for conditional source files
659659
source_deps = collect_source_dependencies(self.modules)
660660
for source_dep in sorted(source_deps, key=lambda d: d.path):
661-
if header := source_dep.get_header():
662-
declarations.emit_line(f'#include "{header}"')
661+
declarations.emit_line(f'#include "{source_dep.get_header()}"')
663662

664663
declarations.emit_line(f'#include "__native{self.short_group_suffix}.h"')
665664
declarations.emit_line()

mypyc/ir/deps.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,23 @@ def __eq__(self, other: object) -> bool:
1919
def __hash__(self) -> int:
2020
return hash(("Capsule", self.name))
2121

22-
def static_data_dep(self) -> SourceDep:
22+
def api_dep(self) -> SourceDep:
2323
module = self.name.split(".")[-1]
24-
return SourceDep(
25-
f"{module}/librt_{module}_static.c", has_header=False, include_dirs=[module]
26-
)
24+
return SourceDep(f"{module}/librt_{module}_api.c", include_dirs=[module])
2725

2826

2927
class SourceDep:
3028
"""Defines a C source file that a primitive may require.
3129
32-
Each source file may also have a corresponding .h file (replace .c with .h)
30+
Each source file must also have a corresponding .h file (replace .c with .h)
3331
that gets implicitly #included if the source is used.
3432
include_dirs are passed to the C compiler when the file is compiled as a
3533
shared library separate from the C extension.
3634
"""
3735

38-
def __init__(
39-
self, path: str, *, has_header: bool = True, include_dirs: list[str] | None = None
40-
) -> None:
36+
def __init__(self, path: str, *, include_dirs: list[str] | None = None) -> None:
4137
# Relative path from mypyc/lib-rt, e.g. 'bytes_extra_ops.c'
4238
self.path: Final = path
43-
self.has_header: Final = has_header
4439
self.include_dirs: Final = include_dirs or []
4540

4641
def __repr__(self) -> str:
@@ -52,9 +47,9 @@ def __eq__(self, other: object) -> bool:
5247
def __hash__(self) -> int:
5348
return hash(("SourceDep", self.path))
5449

55-
def get_header(self) -> str | None:
50+
def get_header(self) -> str:
5651
"""Get the header file path by replacing .c with .h"""
57-
return self.path.replace(".c", ".h") if self.has_header else None
52+
return self.path.replace(".c", ".h")
5853

5954

6055
Dependency = Capsule | SourceDep
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef LIBRT_BASE64_API_H
2+
#define LIBRT_BASE64_API_H
3+
4+
#include "librt_base64.h"
5+
6+
extern void *LibRTBase64_API[LIBRT_BASE64_API_LEN];
7+
8+
#define LibRTBase64_ABIVersion (*(int (*)(void)) LibRTBase64_API[0])
9+
#define LibRTBase64_APIVersion (*(int (*)(void)) LibRTBase64_API[1])
10+
#define LibRTBase64_b64encode_internal (*(PyObject* (*)(PyObject *source, bool urlsafe)) LibRTBase64_API[2])
11+
#define LibRTBase64_b64decode_internal (*(PyObject* (*)(PyObject *source, bool urlsafe)) LibRTBase64_API[3])
12+
13+
int import_librt_base64(void);
14+
15+
#endif // LIBRT_BASE64_API_H

mypyc/lib-rt/base64/librt_base64.h

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,4 @@
77
#define LIBRT_BASE64_API_VERSION 2
88
#define LIBRT_BASE64_API_LEN 4
99

10-
extern void *LibRTBase64_API[LIBRT_BASE64_API_LEN];
11-
12-
#define LibRTBase64_ABIVersion (*(int (*)(void)) LibRTBase64_API[0])
13-
#define LibRTBase64_APIVersion (*(int (*)(void)) LibRTBase64_API[1])
14-
#define LibRTBase64_b64encode_internal (*(PyObject* (*)(PyObject *source, bool urlsafe)) LibRTBase64_API[2])
15-
#define LibRTBase64_b64decode_internal (*(PyObject* (*)(PyObject *source, bool urlsafe)) LibRTBase64_API[3])
16-
17-
static int
18-
import_librt_base64(void)
19-
{
20-
PyObject *mod = PyImport_ImportModule("librt.base64");
21-
if (mod == NULL)
22-
return -1;
23-
Py_DECREF(mod); // we import just for the side effect of making the below work.
24-
void *capsule = PyCapsule_Import("librt.base64._C_API", 0);
25-
if (capsule == NULL)
26-
return -1;
27-
memcpy(LibRTBase64_API, capsule, sizeof(LibRTBase64_API));
28-
if (LibRTBase64_ABIVersion() != LIBRT_BASE64_ABI_VERSION) {
29-
char err[128];
30-
snprintf(err, sizeof(err), "ABI version conflict for librt.base64, expected %d, found %d",
31-
LIBRT_BASE64_ABI_VERSION,
32-
LibRTBase64_ABIVersion()
33-
);
34-
PyErr_SetString(PyExc_ValueError, err);
35-
return -1;
36-
}
37-
if (LibRTBase64_APIVersion() < LIBRT_BASE64_API_VERSION) {
38-
char err[128];
39-
snprintf(err, sizeof(err),
40-
"API version conflict for librt.base64, expected %d or newer, found %d (hint: upgrade librt)",
41-
LIBRT_BASE64_API_VERSION,
42-
LibRTBase64_APIVersion()
43-
);
44-
PyErr_SetString(PyExc_ValueError, err);
45-
return -1;
46-
}
47-
return 0;
48-
}
49-
5010
#endif // LIBRT_BASE64_H
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "librt_base64_api.h"
2+
3+
void *LibRTBase64_API[LIBRT_BASE64_API_LEN] = {0};
4+
5+
int
6+
import_librt_base64(void)
7+
{
8+
PyObject *mod = PyImport_ImportModule("librt.base64");
9+
if (mod == NULL)
10+
return -1;
11+
Py_DECREF(mod); // we import just for the side effect of making the below work.
12+
void *capsule = PyCapsule_Import("librt.base64._C_API", 0);
13+
if (capsule == NULL)
14+
return -1;
15+
memcpy(LibRTBase64_API, capsule, sizeof(LibRTBase64_API));
16+
if (LibRTBase64_ABIVersion() != LIBRT_BASE64_ABI_VERSION) {
17+
char err[128];
18+
snprintf(err, sizeof(err), "ABI version conflict for librt.base64, expected %d, found %d",
19+
LIBRT_BASE64_ABI_VERSION,
20+
LibRTBase64_ABIVersion()
21+
);
22+
PyErr_SetString(PyExc_ValueError, err);
23+
return -1;
24+
}
25+
if (LibRTBase64_APIVersion() < LIBRT_BASE64_API_VERSION) {
26+
char err[128];
27+
snprintf(err, sizeof(err),
28+
"API version conflict for librt.base64, expected %d or newer, found %d (hint: upgrade librt)",
29+
LIBRT_BASE64_API_VERSION,
30+
LibRTBase64_APIVersion()
31+
);
32+
PyErr_SetString(PyExc_ValueError, err);
33+
return -1;
34+
}
35+
return 0;
36+
}

mypyc/lib-rt/base64/librt_base64_static.c

Lines changed: 0 additions & 3 deletions
This file was deleted.

mypyc/lib-rt/byteswriter_extra_ops.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <Python.h>
99

1010
#include "mypyc_util.h"
11-
#include "strings/librt_strings.h"
11+
#include "strings/librt_strings_api.h"
1212
#include "strings/librt_strings_common.h"
1313

1414
// BytesWriter: Length and capacity

mypyc/lib-rt/internal/librt_internal.h

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// API version -- more recent versions must maintain backward compatibility, i.e.
1313
// we can add new features but not remove or change existing features (unless
1414
// ABI version is changed, but see the comment above).
15-
#define LIBRT_INTERNAL_API_VERSION 1
15+
#define LIBRT_INTERNAL_API_VERSION 1
1616

1717
// Number of functions in the capsule API. If you add a new function, also increase
1818
// LIBRT_INTERNAL_API_VERSION.
@@ -44,73 +44,6 @@ static PyTypeObject *WriteBuffer_type_internal(void);
4444
static int NativeInternal_API_Version(void);
4545
static PyObject *extract_symbol_internal(PyObject *data);
4646

47-
#else
48-
49-
extern void *NativeInternal_API[LIBRT_INTERNAL_API_LEN];
50-
51-
#define ReadBuffer_internal (*(PyObject* (*)(PyObject *source)) NativeInternal_API[0])
52-
#define WriteBuffer_internal (*(PyObject* (*)(void)) NativeInternal_API[1])
53-
#define WriteBuffer_getvalue_internal (*(PyObject* (*)(PyObject *source)) NativeInternal_API[2])
54-
#define write_bool_internal (*(char (*)(PyObject *source, char value)) NativeInternal_API[3])
55-
#define read_bool_internal (*(char (*)(PyObject *source)) NativeInternal_API[4])
56-
#define write_str_internal (*(char (*)(PyObject *source, PyObject *value)) NativeInternal_API[5])
57-
#define read_str_internal (*(PyObject* (*)(PyObject *source)) NativeInternal_API[6])
58-
#define write_float_internal (*(char (*)(PyObject *source, double value)) NativeInternal_API[7])
59-
#define read_float_internal (*(double (*)(PyObject *source)) NativeInternal_API[8])
60-
#define write_int_internal (*(char (*)(PyObject *source, CPyTagged value)) NativeInternal_API[9])
61-
#define read_int_internal (*(CPyTagged (*)(PyObject *source)) NativeInternal_API[10])
62-
#define write_tag_internal (*(char (*)(PyObject *source, uint8_t value)) NativeInternal_API[11])
63-
#define read_tag_internal (*(uint8_t (*)(PyObject *source)) NativeInternal_API[12])
64-
#define NativeInternal_ABI_Version (*(int (*)(void)) NativeInternal_API[13])
65-
#define write_bytes_internal (*(char (*)(PyObject *source, PyObject *value)) NativeInternal_API[14])
66-
#define read_bytes_internal (*(PyObject* (*)(PyObject *source)) NativeInternal_API[15])
67-
#define cache_version_internal (*(uint8_t (*)(void)) NativeInternal_API[16])
68-
#define ReadBuffer_type_internal (*(PyTypeObject* (*)(void)) NativeInternal_API[17])
69-
#define WriteBuffer_type_internal (*(PyTypeObject* (*)(void)) NativeInternal_API[18])
70-
#define NativeInternal_API_Version (*(int (*)(void)) NativeInternal_API[19])
71-
#define extract_symbol_internal (*(PyObject* (*)(PyObject *source)) NativeInternal_API[20])
72-
73-
static int
74-
import_librt_internal(void)
75-
{
76-
PyObject *mod = PyImport_ImportModule("librt.internal");
77-
if (mod == NULL)
78-
return -1;
79-
Py_DECREF(mod); // we import just for the side effect of making the below work.
80-
void *capsule = PyCapsule_Import("librt.internal._C_API", 0);
81-
if (capsule == NULL)
82-
return -1;
83-
memcpy(NativeInternal_API, capsule, sizeof(NativeInternal_API));
84-
if (NativeInternal_ABI_Version() != LIBRT_INTERNAL_ABI_VERSION) {
85-
char err[128];
86-
snprintf(err, sizeof(err), "ABI version conflict for librt.internal, expected %d, found %d",
87-
LIBRT_INTERNAL_ABI_VERSION,
88-
NativeInternal_ABI_Version()
89-
);
90-
PyErr_SetString(PyExc_ValueError, err);
91-
return -1;
92-
}
93-
if (NativeInternal_API_Version() < LIBRT_INTERNAL_API_VERSION) {
94-
char err[128];
95-
snprintf(err, sizeof(err),
96-
"API version conflict for librt.internal, expected %d or newer, found %d (hint: upgrade librt)",
97-
LIBRT_INTERNAL_API_VERSION,
98-
NativeInternal_API_Version()
99-
);
100-
PyErr_SetString(PyExc_ValueError, err);
101-
return -1;
102-
}
103-
return 0;
104-
}
105-
10647
#endif
10748

108-
static inline bool CPyReadBuffer_Check(PyObject *obj) {
109-
return Py_TYPE(obj) == ReadBuffer_type_internal();
110-
}
111-
112-
static inline bool CPyWriteBuffer_Check(PyObject *obj) {
113-
return Py_TYPE(obj) == WriteBuffer_type_internal();
114-
}
115-
11649
#endif // LIBRT_INTERNAL_H
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "librt_internal_api.h"
2+
3+
void *NativeInternal_API[LIBRT_INTERNAL_API_LEN] = {0};
4+
5+
int
6+
import_librt_internal(void)
7+
{
8+
PyObject *mod = PyImport_ImportModule("librt.internal");
9+
if (mod == NULL)
10+
return -1;
11+
Py_DECREF(mod); // we import just for the side effect of making the below work.
12+
void *capsule = PyCapsule_Import("librt.internal._C_API", 0);
13+
if (capsule == NULL)
14+
return -1;
15+
memcpy(NativeInternal_API, capsule, sizeof(NativeInternal_API));
16+
if (NativeInternal_ABI_Version() != LIBRT_INTERNAL_ABI_VERSION) {
17+
char err[128];
18+
snprintf(err, sizeof(err), "ABI version conflict for librt.internal, expected %d, found %d",
19+
LIBRT_INTERNAL_ABI_VERSION,
20+
NativeInternal_ABI_Version()
21+
);
22+
PyErr_SetString(PyExc_ValueError, err);
23+
return -1;
24+
}
25+
if (NativeInternal_API_Version() < LIBRT_INTERNAL_API_VERSION) {
26+
char err[128];
27+
snprintf(err, sizeof(err),
28+
"API version conflict for librt.internal, expected %d or newer, found %d (hint: upgrade librt)",
29+
LIBRT_INTERNAL_API_VERSION,
30+
NativeInternal_API_Version()
31+
);
32+
PyErr_SetString(PyExc_ValueError, err);
33+
return -1;
34+
}
35+
return 0;
36+
}

0 commit comments

Comments
 (0)