forked from vyperlang/vyper
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrlp_decoder.py
More file actions
106 lines (94 loc) · 5.68 KB
/
rlp_decoder.py
File metadata and controls
106 lines (94 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
from vyper import (
compile_lll,
optimizer,
)
from vyper.parser.parser_utils import (
LLLnode,
)
def call_data_char(position):
return ['div', ['calldataload', position], 2**248]
def call_data_bytes_as_int(x, b):
return ['seq', ['mstore', sub(32, b), ['calldataload', x]],
['mload', 0]]
def add(x, y):
return ['add', x, y]
def sub(x, y):
return ['sub', x, y]
loop_memory_position = 544
positions = 64
data = 1088
position_index = 2476
data_pos = 2508
c = 2540
i = 2572
L = 2604
position_offset = 2304
rlp_decoder_lll = LLLnode.from_list(
['seq',
['return', [0],
['lll',
['seq',
['mstore', position_index, 0],
['mstore', data_pos, 0],
['mstore', c, call_data_char(0)],
['mstore', i, 0],
['mstore', position_offset, 0],
['assert', ['ge', ['mload', c], 192]], # Must be a list
['if', ['lt', ['mload', c], 248], # if c < 248:
['seq',
['assert', ['eq', ['calldatasize'], sub(['mload', c], 191)]], # assert ~calldatasize() == (c - 191)
['mstore', i, 1]], # i = 1
['seq',
# assert ~calldatasize() == (c - 246) + calldatabytes_as_int(1, c - 247)
['assert', ['eq', ['calldatasize'], add(sub(['mload', c], 246), call_data_bytes_as_int(1, sub(['mload', c], 247)))]],
['mstore', i, sub(['mload', c], 246)]]], # i = c - 246
# Main loop
# Here, we simultaneously build up data in two places:
# (i) starting from memory index 64, a list of 32-byte numbers
# representing the start positions of each value
# (ii) starting from memory index 1088, the values, in format
# <length as 32 byte int> <value>, packed one after the other
['repeat', loop_memory_position, 1, 100,
['seq',
['if', ['ge', ['mload', i], 'calldatasize'], 'break'],
['mstore', c, call_data_char(['mload', i])],
['mstore', add(positions, ['mul', ['mload', position_index], 32]), ['mload', data_pos]],
['mstore', position_index, add(['mload', position_index], 1)],
['if', ['lt', ['mload', c], 128],
['seq',
['mstore', add(data, ['mload', data_pos]), 1],
['calldatacopy', add(data + 32, ['mload', data_pos]), ['mload', i], 1],
['mstore', i, add(['mload', i], 1)],
['mstore', data_pos, add(['mload', data_pos], 33)]],
['if', ['lt', ['mload', c], 184],
['seq',
['mstore', add(data, ['mload', data_pos]), sub(['mload', c], 128)],
['calldatacopy', add(data + 32, ['mload', data_pos]), add(['mload', i], 1), sub(['mload', c], 128)],
['if', ['eq', ['mload', c], 129],
['assert', ['ge', call_data_char(add(['mload', i], 1)), 128]]],
['mstore', i, add(['mload', i], sub(['mload', c], 127))],
['mstore', data_pos, add(['mload', data_pos], sub(['mload', c], 96))]],
['if', ['lt', ['mload', c], 192],
['seq',
['mstore', L, call_data_bytes_as_int(add(['mload', i], 1), sub(['mload', c], 183))],
['assert', ['mul', call_data_char(add(['mload', i], 1)), ['ge', ['mload', L], 56]]],
['mstore', add(data, ['mload', data_pos]), ['mload', L]],
['calldatacopy', add(data + 32, ['mload', data_pos]), add(['mload', i], sub(['mload', c], 182)), ['mload', L]],
['mstore', i, add(add(['mload', i], sub(['mload', c], 182)), ['mload', L])],
['mstore', data_pos, add(['mload', data_pos], add(['mload', L], 32))]],
['invalid']]]]]],
['assert', ['le', ['mload', position_index], 31]],
['mstore', position_offset, add(['mul', ['mload', position_index], 32], 32)],
['mstore', i, sub(['mload', position_offset], 32)],
['repeat', loop_memory_position, 1, 100,
['seq',
['if', ['slt', ['mload', i], 0], 'break'],
['mstore', add(sub(data, ['mload', position_offset]), ['mload', i]), add(['mload', add(positions, ['mload', i])], ['mload', position_offset])],
# ~mstore(data - positionOffset + i, ~mload(positions + i) + positionOffset)
['mstore', i, sub(['mload', i], 32)]]],
['mstore', sub(data, 32), add(['mload', position_offset], ['mload', data_pos])],
['return', sub(data, ['mload', position_offset]), add(['mload', position_offset], ['mload', data_pos])]],
[0]]]]
)
rlp_decoder_lll = optimizer.optimize(rlp_decoder_lll)
rlp_decoder_bytes, _ = compile_lll.assembly_to_evm(compile_lll.compile_to_assembly(rlp_decoder_lll))