10
10
# to make it work for label relocations and directives, etc.
11
11
import pyevmasm as asm
12
12
13
- template_0_1 = """
13
+ template_x_1 = """
14
14
Start:
15
15
PUSH1 Return
16
+ ${pushes}
16
17
PUSH2 Function
17
18
JUMP
18
19
Return:
25
26
Function:
26
27
"""
27
28
28
- template_0_0 = """
29
+ template_x_0 = """
29
30
Start:
30
31
PUSH1 Return
32
+ ${pushes}
31
33
PUSH2 Function
32
34
JUMP
33
35
Return:
34
36
JUMPDEST
35
37
STOP
36
38
Function:
37
39
"""
38
-
39
- template_1_1 = """
40
- Start:
41
- PUSH1 Return
42
- PUSH4 ${input_value}
43
- PUSH2 Function
44
- JUMP
45
- Return:
46
- JUMPDEST
47
- PUSH1 0x00
48
- MSTORE
49
- PUSH1 0x20
50
- PUSH1 0x00
51
- RETURN
52
- Function:
53
- """
54
-
55
- template_2_1 = """
56
- Start:
57
- PUSH1 Return
58
- PUSH4 ${input_value_1}
59
- PUSH4 ${input_value_2}
60
- PUSH2 Function
61
- JUMP
62
- Return:
63
- JUMPDEST
64
- PUSH1 0x00
65
- MSTORE
66
- PUSH1 0x20
67
- PUSH1 0x00
68
- RETURN
69
- Function:
70
- """
71
-
72
- def generate_header_str (inputs : List [int ], output : str ) -> str :
73
- assert len (inputs ) < 3
74
- t = ""
75
- if len (inputs ) is 0 :
76
- if output == "" :
77
- return template_0_0
78
- t = template_0_1
79
- if len (inputs ) is 1 :
80
- t = Template (template_1_1 ).substitute (input_value = inputs [0 ])
81
- elif len (inputs ) is 2 :
82
- t = Template (template_2_1 ).substitute (
83
- input_value_1 = inputs [0 ], input_value_2 = inputs [1 ])
84
- return t
85
-
86
- def generate_function_binary (filename : str , offset : int ) -> str :
87
- assert offset > 0
88
- # being lazy
89
- pass
40
+ def generate_header_str (inputs : List [str ], output : str ) -> str :
41
+ push_list = []
42
+ for input in inputs :
43
+ push = Template ("PUSH4 ${input}" ).substitute (input = input )
44
+ push_list .append (push )
45
+
46
+ t = None
47
+ if output == "" :
48
+ # case X 0
49
+ t = Template (template_x_0 )
50
+ else :
51
+ # case X 1
52
+ t = Template (template_x_1 )
53
+ return t .substitute (pushes = '\n ' .join (push_list ))
90
54
91
55
def generate_contract (inputs : List [int ], output : str , func : str ) -> str :
92
- assert len (inputs ) < 3
93
56
complete_str = generate_header_str (inputs , output ) + func
94
57
assembly = asm .assemble_hex (complete_str )
95
58
return assembly
@@ -98,11 +61,12 @@ def execute_in_evm(code: str, expected: str) -> str:
98
61
# we could use py-evm to do it so everything will be in python.
99
62
emv_path = ""
100
63
try :
101
- emv_path = os .environ ['EVM_PATH' ]
102
- except KeyError (key ):
103
- print ("\" " + key + "\" not defined, using pwd instead" )
64
+ emv_path = os .environ ['EVM_PATH' ] + "/evm"
65
+ except KeyError :
66
+ print ("EVM_PATH not defined, using pwd instead" )
67
+ evm_pth = "evm"
104
68
105
- command = [emv_path + "/ evm" , "--code" , code , "run" ]
69
+ command = [" evm" , "--code" , code , "run" ]
106
70
result = subprocess .run (command , stdout = subprocess .PIPE )
107
71
result .check_returncode ()
108
72
return result .stdout
@@ -183,6 +147,8 @@ def run_assembly(name: str, inputs: List[str], output: str, filename: str) -> No
183
147
result = execute_in_evm (code = contract , expected = output ).decode ("utf-8" )
184
148
success = check_result (name , result , output )
185
149
if not success :
150
+ print ("Generated Assembly: " )
151
+ print (generate_header_str (inputs , output ) + cleaned_content )
186
152
print ("contract: " )
187
153
print (contract )
188
154
return success
@@ -203,28 +169,37 @@ def run_string_input(name: str, inputs: List[str], output: str, function: str) -
203
169
# these are just demos
204
170
"str_test_1_1" : {"input" : ["0x12345678" ],
205
171
"output" : "0x0000000000000000000000000000000000000000000000000000000012345678" ,
206
- "func" : "JUMPDEST\n JUMP" },
172
+ "func" : "JUMPDEST\n SWAP1 \ n JUMP" },
207
173
"str_test_2_1" : {"input" : ["0x12345678" , "0x87654321" ],
208
174
"output" : "0x0000000000000000000000000000000000000000000000000000000099999999" ,
209
175
"func" : "JUMPDEST\n ADD\n SWAP1\n JUMP" },
210
176
}
211
177
212
178
runtime_file_prefix = "../../test/CodeGen/EVM/runtime_tests/"
213
179
file_input_fixtures = {
214
- "file_test_1 " : {
180
+ "simple_test_1.ll " : {
215
181
"input" : [],
216
182
"output" : ["0x000000000000000000000000000000000000000000000000000000001" ],
217
- "file" : "simple_test_1.ll"
218
183
},
219
- "file_test_2 " : {
184
+ "simple_test_2.ll " : {
220
185
"input" : ["0x12345678" , "0x87654321" ],
221
186
"output" : "0x000000000000000000000000000000000000000000000000000000001" ,
222
- "file" : "simple_test_2.ll"
223
187
},
224
- "file_test_3 " : {
188
+ "simple_test_3.ll " : {
225
189
"input" : [],
226
190
"output" : "" ,
227
- "file" : "simple_test_3.ll"
191
+ },
192
+ "simple_test_4.ll" : {
193
+ "input" : ["0x12345678" ],
194
+ "output" : "" ,
195
+ },
196
+ "simple_test_5.ll" : {
197
+ "input" : ["0x12345678" ],
198
+ "output" : "0x000000000000000000000000000000000000000000000000012345679" ,
199
+ },
200
+ "simple_test_6.ll" : {
201
+ "input" : ["0x12345678" , "0x87654321" ],
202
+ "output" : "0x000000000000000000000000000000000000000000000000012345678" ,
228
203
},
229
204
}
230
205
@@ -238,7 +213,7 @@ def execute_tests() -> None:
238
213
for key ,val in file_input_fixtures .items ():
239
214
inputs = val ["input" ]
240
215
output = val ["output" ]
241
- filename = runtime_file_prefix + val [ "file" ]
216
+ filename = runtime_file_prefix + key
242
217
run_assembly (name = key , inputs = inputs , output = output , filename = filename )
243
218
244
219
seed (2019 )
0 commit comments