Skip to content

Commit 8f381b8

Browse files
authored
[mypyc] Tweak how tuple structs are defined (#7630)
Change how we declare and define tuple structs to prepare for separate compilation: * Wrap declarations in an #ifdef/#define so that multiple modules can define the same tuple types (since they are structural) and interoperate properly. * Declare the undefined values eagerly instead of only when they are needed, since they might be needed by another compilationg group. * Declare them with a typedef instead of always writing struct. This will very slightly simplify some logic for manipulating the type string later but mostly just looks better.
1 parent 38f199d commit 8f381b8

File tree

2 files changed

+12
-14
lines changed

2 files changed

+12
-14
lines changed

mypyc/emit.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ def native_function_name(self, fn: FuncDecl) -> str:
152152
return '{}{}'.format(NATIVE_PREFIX, fn.cname(self.names))
153153

154154
def tuple_c_declaration(self, rtuple: RTuple) -> List[str]:
155-
result = ['struct {} {{'.format(rtuple.struct_name)]
155+
result = [
156+
'#ifndef MYPYC_DECLARED_{}'.format(rtuple.struct_name),
157+
'#define MYPYC_DECLARED_{}'.format(rtuple.struct_name),
158+
'typedef struct {} {{'.format(rtuple.struct_name),
159+
]
156160
if len(rtuple.types) == 0: # empty tuple
157161
# Empty tuples contain a flag so that they can still indicate
158162
# error values.
@@ -162,7 +166,11 @@ def tuple_c_declaration(self, rtuple: RTuple) -> List[str]:
162166
for typ in rtuple.types:
163167
result.append('{}f{};'.format(self.ctype_spaced(typ), i))
164168
i += 1
165-
result.append('};')
169+
result.append('}} {};'.format(rtuple.struct_name))
170+
values = self.tuple_undefined_value_helper(rtuple)
171+
result.append('static {} {} = {{ {} }};'.format(
172+
self.ctype(rtuple), self.tuple_undefined_value(rtuple), ''.join(values)))
173+
result.append('#endif')
166174
result.append('')
167175

168176
return result
@@ -183,17 +191,7 @@ def tuple_undefined_check_cond(
183191
tuple_expr_in_c, compare, c_type_compare_val(item_type))
184192

185193
def tuple_undefined_value(self, rtuple: RTuple) -> str:
186-
context = self.context
187-
id = rtuple.unique_id
188-
name = 'tuple_undefined_' + id
189-
if name not in context.declarations:
190-
values = self.tuple_undefined_value_helper(rtuple)
191-
var = 'struct {} {}'.format(rtuple.struct_name, name)
192-
decl = '{};'.format(var)
193-
init = '{} = {{ {} }};'.format(var, ''.join(values))
194-
context.declarations[name] = HeaderDeclaration(
195-
set([rtuple.struct_name]), [decl], [init])
196-
return name
194+
return 'tuple_undefined_' + rtuple.unique_id
197195

198196
def tuple_undefined_value_helper(self, rtuple: RTuple) -> List[str]:
199197
res = []

mypyc/ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ def __init__(self, types: List[RType]) -> None:
248248
self.unique_id = self.accept(TupleNameVisitor())
249249
# Nominally the max c length is 31 chars, but I'm not honestly worried about this.
250250
self.struct_name = 'tuple_{}'.format(self.unique_id)
251-
self._ctype = 'struct {}'.format(self.struct_name)
251+
self._ctype = '{}'.format(self.struct_name)
252252

253253
def accept(self, visitor: 'RTypeVisitor[T]') -> T:
254254
return visitor.visit_rtuple(self)

0 commit comments

Comments
 (0)