hdl.dsl: forbid m.next= inside of FSM but outside of FSM state, too.
[nmigen.git] / nmigen / tracer.py
1 import inspect
2 from opcode import opname
3
4
5 __all__ = ["NameNotFound", "get_var_name"]
6
7
8 class NameNotFound(Exception):
9 pass
10
11
12 def get_var_name(depth=2):
13 frame = inspect.currentframe()
14 for _ in range(depth):
15 frame = frame.f_back
16
17 code = frame.f_code
18 call_index = frame.f_lasti
19 call_opc = opname[code.co_code[call_index]]
20 if call_opc not in ("CALL_FUNCTION", "CALL_FUNCTION_KW", "CALL_FUNCTION_EX", "CALL_METHOD"):
21 return None
22
23 index = call_index + 2
24 while True:
25 opc = opname[code.co_code[index]]
26 if opc in ("STORE_NAME", "STORE_ATTR"):
27 name_index = int(code.co_code[index + 1])
28 return code.co_names[name_index]
29 elif opc == "STORE_FAST":
30 name_index = int(code.co_code[index + 1])
31 return code.co_varnames[name_index]
32 elif opc == "STORE_DEREF":
33 name_index = int(code.co_code[index + 1])
34 return code.co_cellvars[name_index]
35 elif opc in ("LOAD_GLOBAL", "LOAD_ATTR", "LOAD_FAST", "LOAD_DEREF",
36 "DUP_TOP", "BUILD_LIST"):
37 index += 2
38 else:
39 raise NameNotFound