Skip to content

Commit 643a58b

Browse files
authored
[mypyc] Stop abusing module names for static namespacing (#7628)
Currently this is done for modules and finals, using the fictious 'module' and 'final' modules. This will have bad interactions with separate/incremental compilation, so move modules into their own namespace and just put finals in the static namespace in the obvious way.
1 parent cc7667a commit 643a58b

File tree

11 files changed

+102
-94
lines changed

11 files changed

+102
-94
lines changed

mypyc/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
REG_PREFIX = 'cpy_r_' # type: Final # Registers
99
STATIC_PREFIX = 'CPyStatic_' # type: Final # Static variables (for literals etc.)
1010
TYPE_PREFIX = 'CPyType_' # type: Final # Type object struct
11+
MODULE_PREFIX = 'CPyModule_' # type: Final # Cached modules
1112
ATTR_PREFIX = '_' # type: Final # Attributes
1213

1314
ENV_ATTR_NAME = '__mypyc_env__' # type: Final

mypyc/emitfunc.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
"""Code generation for native function bodies."""
22

33

4-
from mypyc.common import REG_PREFIX, NATIVE_PREFIX, STATIC_PREFIX, TYPE_PREFIX
4+
from mypyc.common import (
5+
REG_PREFIX, NATIVE_PREFIX, STATIC_PREFIX, TYPE_PREFIX, MODULE_PREFIX,
6+
)
57
from mypyc.emit import Emitter
68
from mypyc.ops import (
79
FuncIR, OpVisitor, Goto, Branch, Return, Assign, LoadInt, LoadErrorValue, GetAttr, SetAttr,
810
LoadStatic, InitStatic, TupleGet, TupleSet, Call, IncRef, DecRef, Box, Cast, Unbox,
911
BasicBlock, Value, RType, RTuple, MethodCall, PrimitiveOp,
10-
EmitterInterface, Unreachable, NAMESPACE_STATIC, NAMESPACE_TYPE,
12+
EmitterInterface, Unreachable, NAMESPACE_STATIC, NAMESPACE_TYPE, NAMESPACE_MODULE,
1113
RaiseStandardError, FuncDecl, ClassIR,
1214
FUNC_STATICMETHOD, FUNC_CLASSMETHOD,
1315
)
@@ -255,6 +257,7 @@ def visit_set_attr(self, op: SetAttr) -> None:
255257
PREFIX_MAP = {
256258
NAMESPACE_STATIC: STATIC_PREFIX,
257259
NAMESPACE_TYPE: TYPE_PREFIX,
260+
NAMESPACE_MODULE: MODULE_PREFIX,
258261
} # type: Final
259262

260263
def visit_load_static(self, op: LoadStatic) -> None:

mypyc/emitmodule.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from mypy.options import Options
99

1010
from mypyc import genops
11-
from mypyc.common import PREFIX, TOP_LEVEL_NAME, INT_PREFIX
11+
from mypyc.common import PREFIX, TOP_LEVEL_NAME, INT_PREFIX, MODULE_PREFIX
1212
from mypyc.emit import EmitterContext, Emitter, HeaderDeclaration
1313
from mypyc.emitfunc import generate_native_function, native_function_header
1414
from mypyc.emitclass import generate_class_type_decl, generate_class
@@ -145,7 +145,7 @@ def generate_c_for_modules(self) -> List[Tuple[str, str]]:
145145
self.declare_internal_globals(module_name, emitter)
146146
self.declare_imports(module.imports, emitter)
147147
# Finals must be last (types can depend on declared above)
148-
self.define_finals(module.final_names, emitter)
148+
self.define_finals(module_name, module.final_names, emitter)
149149

150150
for cl in module.classes:
151151
if cl.is_ext_class:
@@ -192,7 +192,7 @@ def generate_c_for_modules(self) -> List[Tuple[str, str]]:
192192
declarations.emit_lines(*declaration.decl)
193193

194194
for module_name, module in self.modules:
195-
self.declare_finals(module.final_names, declarations)
195+
self.declare_finals(module_name, module.final_names, declarations)
196196
for cl in module.classes:
197197
generate_class_type_decl(cl, emitter, declarations)
198198
for fn in module.functions:
@@ -456,7 +456,7 @@ def declare_internal_globals(self, module_name: str, emitter: Emitter) -> None:
456456
self.declare_global('PyObject *', static_name)
457457

458458
def module_internal_static_name(self, module_name: str, emitter: Emitter) -> str:
459-
return emitter.static_name('module_internal', module_name)
459+
return emitter.static_name(module_name + '_internal', None, prefix=MODULE_PREFIX)
460460

461461
def declare_module(self, module_name: str, emitter: Emitter) -> None:
462462
# We declare two globals for each module:
@@ -465,22 +465,24 @@ def declare_module(self, module_name: str, emitter: Emitter) -> None:
465465
# by other modules to refer to it.
466466
internal_static_name = self.module_internal_static_name(module_name, emitter)
467467
self.declare_global('CPyModule *', internal_static_name, initializer='NULL')
468-
static_name = emitter.static_name('module', module_name)
468+
static_name = emitter.static_name(module_name, None, prefix=MODULE_PREFIX)
469469
self.declare_global('CPyModule *', static_name)
470470
self.simple_inits.append((static_name, 'Py_None'))
471471

472472
def declare_imports(self, imps: Iterable[str], emitter: Emitter) -> None:
473473
for imp in imps:
474474
self.declare_module(imp, emitter)
475475

476-
def declare_finals(self, final_names: Iterable[Tuple[str, RType]], emitter: Emitter) -> None:
476+
def declare_finals(
477+
self, module: str, final_names: Iterable[Tuple[str, RType]], emitter: Emitter) -> None:
477478
for name, typ in final_names:
478-
static_name = emitter.static_name(name, 'final')
479+
static_name = emitter.static_name(name, module)
479480
emitter.emit_line('extern {}{};'.format(emitter.ctype_spaced(typ), static_name))
480481

481-
def define_finals(self, final_names: Iterable[Tuple[str, RType]], emitter: Emitter) -> None:
482+
def define_finals(
483+
self, module: str, final_names: Iterable[Tuple[str, RType]], emitter: Emitter) -> None:
482484
for name, typ in final_names:
483-
static_name = emitter.static_name(name, 'final')
485+
static_name = emitter.static_name(name, module)
484486
# Here we rely on the fact that undefined value and error value are always the same
485487
if isinstance(typ, RTuple):
486488
# We need to inline because initializer must be static

mypyc/genops.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def f(x: int) -> int:
4646
from mypy.visitor import ExpressionVisitor, StatementVisitor
4747
from mypy.checkexpr import map_actuals_to_formals
4848
from mypy.state import strict_optional_set
49+
from mypy.util import split_target
4950

5051
from mypyc.common import (
5152
ENV_ATTR_NAME, NEXT_LABEL_ATTR_NAME, TEMP_ATTR_NAME, LAMBDA_NAME,
@@ -64,7 +65,8 @@ def f(x: int) -> int:
6465
exc_rtuple,
6566
PrimitiveOp, ControlOp, OpDescription, RegisterOp,
6667
is_object_rprimitive, LiteralsMap, FuncSignature, VTableAttr, VTableMethod, VTableEntries,
67-
NAMESPACE_TYPE, RaiseStandardError, LoadErrorValue, NO_TRACEBACK_LINE_NO, FuncDecl,
68+
NAMESPACE_TYPE, NAMESPACE_MODULE,
69+
RaiseStandardError, LoadErrorValue, NO_TRACEBACK_LINE_NO, FuncDecl,
6870
FUNC_NORMAL, FUNC_STATICMETHOD, FUNC_CLASSMETHOD,
6971
RUnion, is_optional_type, optional_value_type, all_concrete_classes
7072
)
@@ -1365,7 +1367,7 @@ def cache_class_attrs(self, attrs_to_cache: List[Lvalue], cdef: ClassDef) -> Non
13651367
for lval in attrs_to_cache:
13661368
assert isinstance(lval, NameExpr)
13671369
rval = self.py_get_attr(typ, lval.name, cdef.line)
1368-
self.init_final_static(lval, rval, cdef.fullname)
1370+
self.init_final_static(lval, rval, cdef.name)
13691371

13701372
def visit_class_def(self, cdef: ClassDef) -> None:
13711373
ir = self.mapper.type_to_ir[cdef.info]
@@ -1429,7 +1431,7 @@ def visit_class_def(self, cdef: ClassDef) -> None:
14291431
self.primitive_op(
14301432
py_setattr_op, [typ, self.load_static_unicode(lvalue.name), value], stmt.line)
14311433
if self.non_function_scope() and stmt.is_final_def:
1432-
self.init_final_static(lvalue, value, cdef.fullname)
1434+
self.init_final_static(lvalue, value, cdef.name)
14331435
elif isinstance(stmt, ExpressionStmt) and isinstance(stmt.expr, StrExpr):
14341436
# Docstring. Ignore
14351437
pass
@@ -1503,13 +1505,13 @@ def gen_import(self, id: str, line: int) -> None:
15031505
self.imports[id] = None
15041506

15051507
needs_import, out = BasicBlock(), BasicBlock()
1506-
first_load = self.add(LoadStatic(object_rprimitive, 'module', id))
1508+
first_load = self.load_module(id)
15071509
comparison = self.binary_op(first_load, self.none_object(), 'is not', line)
15081510
self.add_bool_branch(comparison, out, needs_import)
15091511

15101512
self.activate_block(needs_import)
15111513
value = self.primitive_op(import_op, [self.load_static_unicode(id)], line)
1512-
self.add(InitStatic(value, 'module', id))
1514+
self.add(InitStatic(value, id, namespace=NAMESPACE_MODULE))
15131515
self.goto_and_activate(out)
15141516

15151517
def visit_import(self, node: Import) -> None:
@@ -1555,7 +1557,7 @@ def visit_import_from(self, node: ImportFrom) -> None:
15551557
id = importlib.util.resolve_name('.' * node.relative + node.id, module_package)
15561558

15571559
self.gen_import(id, node.line)
1558-
module = self.add(LoadStatic(object_rprimitive, 'module', id))
1560+
module = self.load_module(id)
15591561

15601562
# Copy everything into our module's dict.
15611563
# Note that we miscompile import from inside of functions here,
@@ -1708,7 +1710,7 @@ def calculate_arg_defaults(self,
17081710
env.lookup(arg.variable).type, arg.line)
17091711
if not fn_info.is_nested:
17101712
name = fitem.fullname() + '.' + arg.variable.name()
1711-
self.add(InitStatic(value, name, 'final'))
1713+
self.add(InitStatic(value, name, self.module_name))
17121714
else:
17131715
assert func_reg is not None
17141716
self.add(SetAttr(func_reg, arg.variable.name(), value, arg.line))
@@ -1736,7 +1738,7 @@ def get_default() -> Value:
17361738
elif not self.fn_info.is_nested:
17371739
name = fitem.fullname() + '.' + arg.variable.name()
17381740
self.final_names.append((name, target.type))
1739-
return self.add(LoadStatic(target.type, name, 'final'))
1741+
return self.add(LoadStatic(target.type, name, self.module_name))
17401742
else:
17411743
name = arg.variable.name()
17421744
self.fn_info.callable_class.ir.attributes[name] = target.type
@@ -2020,19 +2022,21 @@ def init_final_static(self, lvalue: Lvalue, rvalue_reg: Value,
20202022
assert isinstance(lvalue.node, Var)
20212023
if lvalue.node.final_value is None:
20222024
if class_name is None:
2023-
name = lvalue.fullname
2025+
name = lvalue.name
20242026
else:
20252027
name = '{}.{}'.format(class_name, lvalue.name)
20262028
assert name is not None, "Full name not set for variable"
20272029
self.final_names.append((name, rvalue_reg.type))
2028-
self.add(InitStatic(rvalue_reg, name, 'final'))
2030+
self.add(InitStatic(rvalue_reg, name, self.module_name))
20292031

20302032
def load_final_static(self, fullname: str, typ: RType, line: int,
20312033
error_name: Optional[str] = None) -> Value:
20322034
if error_name is None:
20332035
error_name = fullname
20342036
ok_block, error_block = BasicBlock(), BasicBlock()
2035-
value = self.add(LoadStatic(typ, fullname, 'final', line=line))
2037+
split_name = split_target(self.graph, fullname)
2038+
assert split_name is not None
2039+
value = self.add(LoadStatic(typ, split_name[1], split_name[0], line=line))
20362040
self.add(Branch(value, error_block, ok_block, Branch.IS_ERROR, rare=True))
20372041
self.activate_block(error_block)
20382042
self.add(RaiseStandardError(RaiseStandardError.VALUE_ERROR,
@@ -5215,7 +5219,7 @@ def load_static_unicode(self, value: str) -> Value:
52155219
return self.add(LoadStatic(str_rprimitive, static_symbol, ann=value))
52165220

52175221
def load_module(self, name: str) -> Value:
5218-
return self.add(LoadStatic(object_rprimitive, 'module', name))
5222+
return self.add(LoadStatic(object_rprimitive, name, namespace=NAMESPACE_MODULE))
52195223

52205224
def load_module_attr_by_fullname(self, fullname: str, line: int) -> Value:
52215225
module, _, name = fullname.rpartition('.')

mypyc/ops.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,7 @@ def accept(self, visitor: 'OpVisitor[T]') -> T:
11151115

11161116
NAMESPACE_STATIC = 'static' # type: Final # Default name space for statics, variables
11171117
NAMESPACE_TYPE = 'type' # type: Final # Static namespace for pointers to native type objects
1118+
NAMESPACE_MODULE = 'module' # type: Final # Namespace for modules
11181119

11191120

11201121
class LoadStatic(RegisterOp):

mypyc/test-data/analysis.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ L1:
530530
goto L10
531531
L2:
532532
r1 = error_catch
533-
r2 = builtins.module :: static
533+
r2 = builtins :: module
534534
r3 = unicode_1 :: static ('Exception')
535535
r4 = getattr r2, r3
536536
if is_error(r4) goto L8 (error at lol:4) else goto L3

mypyc/test-data/exceptions.test

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def g():
194194
r12, r13 :: None
195195
L0:
196196
L1:
197-
r0 = builtins.module :: static
197+
r0 = builtins :: module
198198
r1 = unicode_1 :: static ('object')
199199
r2 = getattr r0, r1
200200
if is_error(r2) goto L3 (error at g:3) else goto L2
@@ -205,7 +205,7 @@ L2:
205205
L3:
206206
r4 = error_catch
207207
r5 = unicode_2 :: static ('weeee')
208-
r6 = builtins.module :: static
208+
r6 = builtins :: module
209209
r7 = unicode_3 :: static ('print')
210210
r8 = getattr r6, r7
211211
if is_error(r8) goto L7 (error at g:5) else goto L4
@@ -266,7 +266,7 @@ def a():
266266
r20 :: str
267267
L0:
268268
L1:
269-
r0 = builtins.module :: static
269+
r0 = builtins :: module
270270
r1 = unicode_1 :: static ('print')
271271
r2 = getattr r0, r1
272272
if is_error(r2) goto L6 (error at a:3) else goto L2
@@ -293,7 +293,7 @@ L6:
293293
r7 = r11
294294
L7:
295295
r12 = unicode_3 :: static ('goodbye!')
296-
r13 = builtins.module :: static
296+
r13 = builtins :: module
297297
r14 = unicode_1 :: static ('print')
298298
r15 = getattr r13, r14
299299
if is_error(r15) goto L15 (error at a:6) else goto L8
@@ -500,7 +500,7 @@ L2:
500500
r3 = !r2
501501
if r3 goto L12 else goto L1 :: bool
502502
L3:
503-
r4 = builtins.module :: static
503+
r4 = builtins :: module
504504
r5 = unicode_3 :: static ('print')
505505
r6 = getattr r4, r5
506506
if is_error(r6) goto L13 (error at f:7) else goto L4

0 commit comments

Comments
 (0)