pycdc gives wrong code when dealing with swapping two variables
pycdc gives wrong code when dealing with swapping two variables:
pycdas:
102 LOAD_FAST 2: sbox
104 LOAD_FAST 3: j
106 BINARY_SUBSCR
108 LOAD_FAST 2: sbox
110 LOAD_FAST 8: i
112 BINARY_SUBSCR
114 ROT_TWO
116 LOAD_FAST 2: sbox
118 LOAD_FAST 8: i
120 STORE_SUBSCR
122 LOAD_FAST 2: sbox
124 LOAD_FAST 3: j
126 STORE_SUBSCR
pycdc:
sbox[i] = sbox[j]
sbox[j] = sbox[i]
origin:
sbox[i], sbox[j] = sbox[j], sbox[i]
Hello, but isn't it how it would looks like in 2 lines ? Pycdc might not always be able to get back a 1:1 code too.
@TheHellTower the two pieces of code are not equivalent. The original swaps values of sbox[i] and sbox[j] while the second with is the same as sbox[i] = sbox[j] (the second assignment statement could be removed altogether).
@TheHellTower the two pieces of code are not equivalent. The original swaps values of
sbox[i]andsbox[j]while the second with is the same assbox[i] = sbox[j](the second assignment statement could be removed altogether).
Hey, sorry I'm back, I might try to look at it and see if I can get it solved !
And for me it looks correct because I seen things similar like:
a, b = 1, 2
a = 1
b = 2
If you have a more detailed explanation don't hesitate because I don't really get it well if I'm wrong right now..
When pycdc processes the code you provided, it is indeed correct, but it is unrelated to the current issue. The code you provided is a tuple unpacking operation at the Python bytecode level, rather than the variable swapping operation I mentioned earlier. The following code may give you a more intuitive understanding of this issue.
a = 1
b = 2
a, b = b, a
print(f"a = {a}, b = {b}")
the result of pycdas:
0 LOAD_CONST 0: (1, 2)
2 UNPACK_SEQUENCE 2
4 STORE_NAME 0: a
6 STORE_NAME 1: b
8 LOAD_NAME 2: print
10 LOAD_CONST 1: 'a = '
12 LOAD_NAME 0: a
14 FORMAT_VALUE 0
16 LOAD_CONST 2: ', b = '
18 LOAD_NAME 1: b
20 FORMAT_VALUE 0
22 BUILD_STRING 4
24 CALL_FUNCTION 1
26 POP_TOP
28 LOAD_CONST 3: None
30 RETURN_VALUE
As I mentioned earlier, its core is the UNPACK_SEQUENCE instruction, which is tuple unpacking. However, the issue here is swapping, and the following is an example of swapping.
a = 1
b = 2
a, b = b, a
print(f"a = {a}, b = {b}")
the result of pycdas:
0 LOAD_CONST 0: 1
2 STORE_NAME 0: a
4 LOAD_CONST 1: 2
6 STORE_NAME 1: b
8 LOAD_NAME 1: b
10 LOAD_NAME 0: a
12 ROT_TWO
14 STORE_NAME 0: a
16 STORE_NAME 1: b
18 LOAD_NAME 2: print
20 LOAD_CONST 2: 'a = '
22 LOAD_NAME 0: a
24 FORMAT_VALUE 0
26 LOAD_CONST 3: ', b = '
28 LOAD_NAME 1: b
30 FORMAT_VALUE 0
32 BUILD_STRING 4
34 CALL_FUNCTION 1
36 POP_TOP
38 LOAD_CONST 4: None
40 RETURN_VALUE
The core of this is the ROT_TWO instruction.
The following is an experiment demonstrating the incorrect code provided by pycdc:
attachment: pycdc_swap_issues.tar.gz
When pycdc processes the code you provided, it is indeed correct, but it is unrelated to the current issue. The code you provided is a tuple unpacking operation at the Python bytecode level, rather than the variable swapping operation I mentioned earlier. The following code may give you a more intuitive understanding of this issue.
a = 1 b = 2 a, b = b, a print(f"a = {a}, b = {b}")the result of pycdas:
0 LOAD_CONST 0: (1, 2) 2 UNPACK_SEQUENCE 2 4 STORE_NAME 0: a 6 STORE_NAME 1: b 8 LOAD_NAME 2: print 10 LOAD_CONST 1: 'a = ' 12 LOAD_NAME 0: a 14 FORMAT_VALUE 0 16 LOAD_CONST 2: ', b = ' 18 LOAD_NAME 1: b 20 FORMAT_VALUE 0 22 BUILD_STRING 4 24 CALL_FUNCTION 1 26 POP_TOP 28 LOAD_CONST 3: None 30 RETURN_VALUEAs I mentioned earlier, its core is the UNPACK_SEQUENCE instruction, which is tuple unpacking. However, the issue here is swapping, and the following is an example of swapping.
a = 1 b = 2 a, b = b, a print(f"a = {a}, b = {b}")the result of pycdas:
0 LOAD_CONST 0: 1 2 STORE_NAME 0: a 4 LOAD_CONST 1: 2 6 STORE_NAME 1: b 8 LOAD_NAME 1: b 10 LOAD_NAME 0: a 12 ROT_TWO 14 STORE_NAME 0: a 16 STORE_NAME 1: b 18 LOAD_NAME 2: print 20 LOAD_CONST 2: 'a = ' 22 LOAD_NAME 0: a 24 FORMAT_VALUE 0 26 LOAD_CONST 3: ', b = ' 28 LOAD_NAME 1: b 30 FORMAT_VALUE 0 32 BUILD_STRING 4 34 CALL_FUNCTION 1 36 POP_TOP 38 LOAD_CONST 4: None 40 RETURN_VALUEThe core of this is the ROT_TWO instruction.
The following is an experiment demonstrating the incorrect code provided by pycdc:
attachment: pycdc_swap_issues.tar.gz
Hello, yeah now I get your problem.. I suppose for these cases we should first save the 2 values then swap them then.. To avoid getting this problem again, I don't have a perfect and clean-code idea to achieve this but I will see in the next days if I can fix it but can't promise, thanks for clarifying it and giving out the OPCode that generate the core problem !
