Skip to content

Commit b11ba39

Browse files
nludbandpgeorge
authored andcommitted
rp2/modules: Fix memory leak and logic bug in handling of _pio_funcs.
The `rp2` package use a global dict `_pio_funcs` to populate a namespace for `@asm_pio` functions to be executed in. That dict is not cleaned up after use, keeping references to bound methods of a `PIOASMEmit`. By not setting/clearing all the functions, `asm_pio_encode` unintentionally allows the use of the old directives (harmless) as well as `jmp` (in general, produces the wrong output). Fix that by making sure `_pio_funcs` is returned to its original state after using it: - For `@asm_pio` update the target dict from `_pio_funcs` and then set additional functions as needed, leaving `_pio_funcs` unchanged. - For `asm_pio_encode`, borrow `_pio_funcs` to use as globals (avoiding a bunch of memory alloc/free) but delete the instruction entries after use. Signed-off-by: Neil Ludban <neil.ludban@gmail.com>
1 parent 11c9656 commit b11ba39

File tree

1 file changed

+42
-49
lines changed

1 file changed

+42
-49
lines changed

ports/rp2/modules/rp2.py

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -215,58 +215,55 @@ def set(self, dest, data):
215215
# "block": see above
216216
"clear": 0x40,
217217
"rel": lambda x: x | 0x10,
218-
# functions
219-
"wrap_target": None,
220-
"wrap": None,
221-
"label": None,
222-
"word": None,
223-
"nop": None,
224-
"jmp": None,
225-
"wait": None,
226-
"in_": None,
227-
"out": None,
228-
"push": None,
229-
"pull": None,
230-
"mov": None,
231-
"irq": None,
232-
"set": None,
233218
}
234219

235220

221+
_pio_directives = (
222+
"wrap_target",
223+
"wrap",
224+
"label",
225+
)
226+
227+
228+
_pio_instructions = (
229+
"word",
230+
"nop",
231+
"jmp",
232+
"wait",
233+
"in_",
234+
"out",
235+
"push",
236+
"pull",
237+
"mov",
238+
"irq",
239+
"set",
240+
)
241+
242+
236243
def asm_pio(**kw):
237244
emit = PIOASMEmit(**kw)
238245

239246
def dec(f):
240247
nonlocal emit
241248

242-
gl = _pio_funcs
243-
gl["wrap_target"] = emit.wrap_target
244-
gl["wrap"] = emit.wrap
245-
gl["label"] = emit.label
246-
gl["word"] = emit.word
247-
gl["nop"] = emit.nop
248-
gl["jmp"] = emit.jmp
249-
gl["wait"] = emit.wait
250-
gl["in_"] = emit.in_
251-
gl["out"] = emit.out
252-
gl["push"] = emit.push
253-
gl["pull"] = emit.pull
254-
gl["mov"] = emit.mov
255-
gl["irq"] = emit.irq
256-
gl["set"] = emit.set
257-
258-
old_gl = f.__globals__.copy()
259-
f.__globals__.clear()
260-
f.__globals__.update(gl)
249+
gl = f.__globals__
250+
old_gl = gl.copy()
251+
gl.clear()
252+
253+
gl.update(_pio_funcs)
254+
for name in _pio_directives:
255+
gl[name] = getattr(emit, name)
256+
for name in _pio_instructions:
257+
gl[name] = getattr(emit, name)
261258

262259
emit.start_pass(0)
263260
f()
264261

265262
emit.start_pass(1)
266263
f()
267264

268-
f.__globals__.clear()
269-
f.__globals__.update(old_gl)
265+
gl.clear()
266+
gl.update(old_gl)
270267

271268
return emit.prog
272269

@@ -284,19 +281,15 @@ def asm_pio_encode(instr, sideset_count, sideset_opt=False):
284281
emit.num_sideset = 0
285282

286283
gl = _pio_funcs
287-
gl["word"] = emit.word
288-
gl["nop"] = emit.nop
289-
# gl["jmp"] = emit.jmp currently not supported
290-
gl["wait"] = emit.wait
291-
gl["in_"] = emit.in_
292-
gl["out"] = emit.out
293-
gl["push"] = emit.push
294-
gl["pull"] = emit.pull
295-
gl["mov"] = emit.mov
296-
gl["irq"] = emit.irq
297-
gl["set"] = emit.set
298-
299-
exec(instr, gl)
284+
for name in _pio_instructions:
285+
gl[name] = getattr(emit, name)
286+
gl["jmp"] = None # emit.jmp currently not supported
287+
288+
try:
289+
exec(instr, gl)
290+
finally:
291+
for name in _pio_instructions:
292+
del gl[name]
300293

301294
if len(emit.prog[_PROG_DATA]) != 1:
302295
raise PIOASMError("expecting exactly 1 instruction")

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy