Skip to content

Commit 335b49d

Browse files
jbower-fbmeta-codesync[bot]
authored andcommitted
Add optional + struct to UpstreamBorrow
Summary: The ability to mark things as optional means we can have the script fail if non-optional things are missing. Otherwise it's very confusing when the script is okay but things are missing. Things might be optional if they depend on compile time flags (like `Py_DEBUG` or `Py_GIL_DISABLED`). I can't think of a simple way of controlling things by the macro flags directly. The ability to borrow struct types is just because I made the two things together for following diffs and it seems more work than it's worth to separate them. Reviewed By: alexmalyshev Differential Revision: D91197755 fbshipit-source-id: 5ef31e55f1e581d307801c0621296b85bed5c452
1 parent eb427cb commit 335b49d

5 files changed

Lines changed: 31 additions & 22 deletions

File tree

cinderx/Interpreter/3.14/borrowed-ceval.c.template

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ int _Py_CheckRecursiveCallPy(PyThreadState* tstate);
4141
// @Borrow var _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS from Python/ceval.c
4242

4343
// @Borrow function do_raise from Python/ceval.c
44-
// @Borrow function dump_item from Python/ceval.c
45-
// @Borrow function dump_stack from Python/ceval.c
46-
// @Borrow function lltrace_instruction from Python/ceval.c
47-
// @Borrow function lltrace_resume_frame from Python/ceval.c
4844

49-
// @Borrow function maybe_lltrace_resume_frame from Python/ceval.c
45+
// These are all optional because they are only present + used in debug builds
46+
// @Borrow optional function dump_item from Python/ceval.c
47+
// @Borrow optional function dump_stack from Python/ceval.c
48+
// @Borrow optional function lltrace_instruction from Python/ceval.c
49+
// @Borrow optional function lltrace_resume_frame from Python/ceval.c
50+
// @Borrow optional function maybe_lltrace_resume_frame from Python/ceval.c
51+
5052
// @Borrow function do_monitor_exc from Python/ceval.c
5153
// @Borrow function no_tools_for_global_event from Python/ceval.c
5254
// @Borrow function no_tools_for_local_event from Python/ceval.c

cinderx/Interpreter/3.14/ceval.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
172172
Py_XDECREF(cause);
173173
return 0;
174174
}
175+
176+
// These are all optional because they are only present + used in debug builds
175177
static void
176178
dump_item(_PyStackRef item)
177179
{
@@ -279,7 +281,6 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
279281
fflush(stdout);
280282
PyErr_SetRaisedException(exc);
281283
}
282-
283284
static int
284285
maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, PyObject *globals)
285286
{
@@ -306,6 +307,7 @@ maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, PyObject *globals)
306307
}
307308
return lltrace;
308309
}
310+
309311
static int
310312
do_monitor_exc(PyThreadState *tstate, _PyInterpreterFrame *frame,
311313
_Py_CODEUNIT *instr, int event)

cinderx/UpstreamBorrow/UpstreamBorrow.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
r".*// @Borrow CPP directives noinclude from (\S+)" + VERSION_AND_TRANSFORM
2222
)
2323
BORROW_DECL_PATTERN: re.Pattern[str] = re.compile(
24-
r"// @Borrow (function|typedef|var) (\S+) from (\S+)" + VERSION_AND_TRANSFORM
24+
r"// @Borrow (optional )?(function|typedef|var|struct|enum) (\S+) from (\S+)"
25+
+ VERSION_AND_TRANSFORM
2526
)
2627
CPP_DIRECTIVE_PATTERN: re.Pattern[str] = re.compile(
2728
r"#\s*(define|undef|if|elif|else|endif|include)"
@@ -67,6 +68,7 @@ class Decl:
6768
source_file: str
6869
version: str | None
6970
transform: str | None
71+
optional: bool = False
7072

7173

7274
@dataclass
@@ -80,11 +82,12 @@ def parse_borrow_info(input_string: str) -> Decl | None:
8082
if not match:
8183
return None
8284

83-
kind_str = match.group(1)
84-
name = match.group(2)
85-
source_file = match.group(3)
86-
version = match.group(4) # not used for anything, but generated by callgraph.py
87-
transform = match.group(5)
85+
optional = match.group(1) is not None
86+
kind_str = match.group(2)
87+
name = match.group(3)
88+
source_file = match.group(4)
89+
version = match.group(5) # not used for anything, but generated by callgraph.py
90+
transform = match.group(6)
8891

8992
if kind_str == "function":
9093
# pyre-ignore[16]: `CursorKind` has no attribute `FUNCTION_DECL`.
@@ -95,13 +98,18 @@ def parse_borrow_info(input_string: str) -> Decl | None:
9598
elif kind_str == "var":
9699
# pyre-ignore[16]: `CursorKind` has no attribute `VAR_DECL`.
97100
kind = CursorKind.VAR_DECL
101+
elif kind_str == "struct":
102+
# pyre-ignore[16]: `CursorKind` has no attribute `STRUCT_DECL`.
103+
kind = CursorKind.STRUCT_DECL
98104
elif kind_str == "enum":
99105
# pyre-ignore[16]: `CursorKind` has no attribute `ENUM_DECL`.
100106
kind = CursorKind.ENUM_DECL
101107
else:
102108
raise Exception(f"Unknown kind: {kind_str}")
103109

104-
return Decl(kind, name, source_file, version, transform[1:] if transform else None)
110+
return Decl(
111+
kind, name, source_file, version, transform[1:] if transform else None, optional
112+
)
105113

106114

107115
def transform_eval_frame(lines: list[str]) -> list[str]:
@@ -217,11 +225,14 @@ def _generate_output(self) -> None:
217225
out = []
218226
for line in self.input_lines:
219227
match line:
220-
case Decl(kind, name, source_file, _, transform):
228+
case Decl(kind, name, source_file, _, transform, optional):
221229
lines = self.decls[source_file].get(name)
222230
if lines is None:
223-
print(f"Could not find {kind} for '{name}' in {source_file}")
224-
continue
231+
if optional:
232+
continue
233+
raise Exception(
234+
f"Could not find {kind} for '{name}' in {source_file}"
235+
)
225236
# Apply custom transformation if one exists for this function
226237
if transform in TRANSFORMS:
227238
lines = TRANSFORMS[transform](lines)

cinderx/UpstreamBorrow/borrowed-3.15.c.template

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,11 @@ PyDictKeysObject* ci_dict_empty_keys;
140140
// @Borrow function unicodekeys_lookup_unicode from Objects/dictobject.c [3.15]
141141
// @Borrow function unicodekeys_lookup_generic from Objects/dictobject.c [3.15]
142142
// @Borrow function dictkeys_generic_lookup from Objects/dictobject.c [3.15]
143-
// @Borrow function _Py_dict_lookup_keep_lazy from Objects/dictobject.c [3.15]
144143
// @Borrow function lookdict_index from Objects/dictobject.c [3.15]
145144
// @Borrow function delete_index_from_values from Objects/dictobject.c [3.15]
146145
// @Borrow function dictkeys_set_index from Objects/dictobject.c [3.15]
147146
// @Borrow function delitem_common from Objects/dictobject.c [3.15]
148-
// @Borrow function delitem_knownhash_lock_held from Objects/dictobject.c [3.15]
149147
// @Borrow function new_keys_object from Objects/dictobject.c [3.15]
150-
// @Borrow function lazy_import_verbose from Objects/dictobject.c [3.15]
151148
// @Borrow function insert_to_emptydict from Objects/dictobject.c [3.15]
152149
// @Borrow function ensure_shared_on_resize from Objects/dictobject.c [3.15]
153150
// @Borrow function build_indices_generic from Objects/dictobject.c [3.15]
@@ -526,8 +523,6 @@ LONG_FLOAT_ACTION(compactlong_float_true_div, /)
526523
// @Borrow function tb_create_raw from Python/traceback.c [3.15]
527524
// @Borrow function _PyTraceBack_FromFrame from Python/traceback.c [3.15]
528525

529-
// @Borrow function _PyFloat_FromDouble_ConsumeInputs from Objects/floatobject.c [3.15]
530-
531526
// Internal dependencies for gen_dealloc.
532527
// @Borrow function gen_clear_frame from Objects/genobject.c [3.15]
533528
// End internal dependencies.

cinderx/UpstreamBorrow/borrowed-3.15.gen_cached.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5597,7 +5597,6 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
55975597
return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, -1);
55985598
}
55995599

5600-
56015600
// Internal dependencies for gen_dealloc.
56025601
static void
56035602
gen_clear_frame(PyGenObject *gen)

0 commit comments

Comments
 (0)