@@ -27,7 +27,7 @@ use crate::{
27
27
28
28
#[ allow( dead_code) ]
29
29
pub struct CairoRunner2 {
30
- virtual_machine : VirtualMachine ,
30
+ vm : VirtualMachine ,
31
31
program_base : Relocatable ,
32
32
execution_base : Relocatable ,
33
33
final_pc : Relocatable ,
@@ -56,66 +56,37 @@ impl CairoRunner2 {
56
56
identifiers : HashMap < String , Identifier > ,
57
57
reference_manager : Vec < HintReference > ,
58
58
) -> Result < Self , RunnerError > {
59
- let entrypoint = executable
60
- . entrypoints
61
- . iter ( )
62
- . find ( |entrypoint| {
63
- // TODO: Use `Eq` once implemented on `EntryPointKind`.
64
- std:: mem:: discriminant ( & entrypoint. kind ) == std:: mem:: discriminant ( & entrypoint_kind)
65
- } )
66
- . expect ( "executable had no entrypoint of required kind" ) ;
59
+ let entrypoint = find_entrypoint_of_kind ( & executable. entrypoints , entrypoint_kind. clone ( ) ) ;
67
60
68
61
let builtins = get_entrypoint_builtins ( entrypoint) ;
69
62
70
63
check_builtin_order ( & builtins) ?;
64
+ let mut builtin_runners = initialize_builtin_runners ( & layout, & builtins, true , true ) ?;
71
65
72
- let builtins_set: HashSet < BuiltinName > = builtins. clone ( ) . into_iter ( ) . collect ( ) ;
73
- let mut builtin_runners = initialize_builtin_runners ( & layout, builtins_set, true , true ) ?;
74
-
75
- let mut memory_segment_manager = MemorySegmentManager :: new ( ) ;
76
- let program_base = memory_segment_manager. add ( ) ;
77
- let execution_base = memory_segment_manager. add ( ) ;
66
+ let mut segments = MemorySegmentManager :: new ( ) ;
67
+ let program_base = segments. add ( ) ;
68
+ let execution_base = segments. add ( ) ;
78
69
79
- for builtin_runner in & mut builtin_runners {
80
- builtin_runner. initialize_segments ( & mut memory_segment_manager) ;
81
- }
70
+ initialize_builtin_runner_segments ( & mut builtin_runners, & mut segments) ;
82
71
83
- for builtin_runner in & mut builtin_runners {
84
- if let BuiltinRunner :: Mod ( runner) = builtin_runner {
85
- runner. initialize_zero_segment ( & mut memory_segment_manager) ;
86
- }
87
- }
88
-
89
- let mut virtual_machine = VirtualMachineBuilder :: default ( )
72
+ let mut vm = VirtualMachineBuilder :: default ( )
90
73
. builtin_runners ( builtin_runners)
91
- . segments ( memory_segment_manager )
74
+ . segments ( segments )
92
75
. build ( ) ;
93
76
94
- let builtin_runner_map: HashMap < BuiltinName , & BuiltinRunner > = virtual_machine
95
- . builtin_runners
96
- . iter ( )
97
- . map ( |builtin_runner| ( builtin_runner. name ( ) , builtin_runner) )
98
- . collect ( ) ;
99
77
let mut stack = Vec :: new ( ) ;
100
- for builtin in builtins {
101
- if let Some ( builtin_runner) = builtin_runner_map. get ( & builtin) {
102
- stack. append ( & mut builtin_runner. initial_stack ( ) ) ;
103
- } else {
104
- stack. push ( Felt252 :: ZERO . into ( ) )
105
- }
106
- }
78
+ extend_stack_with_builtins ( & mut stack, & builtins, & vm. builtin_runners ) ;
107
79
108
- let return_fp = virtual_machine . add_memory_segment ( ) ;
109
- let return_pc = virtual_machine . add_memory_segment ( ) ;
80
+ let return_fp = vm . add_memory_segment ( ) ;
81
+ let return_pc = vm . add_memory_segment ( ) ;
110
82
stack. push ( MaybeRelocatable :: RelocatableValue ( return_fp) ) ;
111
83
stack. push ( MaybeRelocatable :: RelocatableValue ( return_pc) ) ;
112
84
113
85
let initial_pc = ( program_base + entrypoint. offset ) ?;
114
86
let initial_fp = ( execution_base + stack. len ( ) ) ?;
115
87
let initial_ap = initial_fp;
116
-
117
88
let run_context = RunContext :: new ( initial_pc, initial_ap. offset , initial_fp. offset ) ;
118
- virtual_machine . set_run_context ( run_context) ;
89
+ vm . set_run_context ( run_context) ;
119
90
120
91
let bytecode = executable
121
92
. program
@@ -124,28 +95,19 @@ impl CairoRunner2 {
124
95
. map ( Felt252 :: from)
125
96
. map ( MaybeRelocatable :: from)
126
97
. collect :: < Vec < _ > > ( ) ;
127
-
128
- virtual_machine
129
- . load_data ( program_base, & bytecode)
98
+ vm. load_data ( program_base, & bytecode)
130
99
. map_err ( RunnerError :: MemoryInitializationError ) ?;
131
-
132
100
for i in 0 ..bytecode. len ( ) {
133
- virtual_machine
134
- . segments
135
- . memory
136
- . mark_as_accessed ( ( program_base + i) ?) ;
101
+ vm. segments . memory . mark_as_accessed ( ( program_base + i) ?) ;
137
102
}
138
103
139
- virtual_machine
140
- . load_data ( execution_base, & stack)
104
+ vm. load_data ( execution_base, & stack)
141
105
. map_err ( RunnerError :: MemoryInitializationError ) ?;
142
106
143
- for builtin_runner in & mut virtual_machine . builtin_runners {
144
- builtin_runner. add_validation_rule ( & mut virtual_machine . segments . memory )
107
+ for builtin_runner in & mut vm . builtin_runners {
108
+ builtin_runner. add_validation_rule ( & mut vm . segments . memory )
145
109
}
146
-
147
- virtual_machine
148
- . segments
110
+ vm. segments
149
111
. memory
150
112
. validate_existing_memory ( )
151
113
. map_err ( RunnerError :: MemoryValidationError ) ?;
@@ -157,7 +119,7 @@ impl CairoRunner2 {
157
119
158
120
Ok ( Self {
159
121
executable,
160
- virtual_machine ,
122
+ vm ,
161
123
program_base,
162
124
execution_base,
163
125
final_pc,
@@ -177,6 +139,52 @@ impl CairoRunner2 {
177
139
}
178
140
}
179
141
142
+ fn find_entrypoint_of_kind (
143
+ entrypoints : & [ ExecutableEntryPoint ] ,
144
+ entrypoint_kind : EntryPointKind ,
145
+ ) -> & ExecutableEntryPoint {
146
+ entrypoints
147
+ . iter ( )
148
+ . find ( |entrypoint| {
149
+ // TODO: Use `Eq` once implemented on `EntryPointKind`.
150
+ std:: mem:: discriminant ( & entrypoint. kind ) == std:: mem:: discriminant ( & entrypoint_kind)
151
+ } )
152
+ . expect ( "executable had no entrypoint of required kind" )
153
+ }
154
+
155
+ fn extend_stack_with_builtins (
156
+ stack : & mut Vec < MaybeRelocatable > ,
157
+ builtins : & [ BuiltinName ] ,
158
+ runners : & [ BuiltinRunner ] ,
159
+ ) {
160
+ let runner_map: HashMap < BuiltinName , & BuiltinRunner > = runners
161
+ . iter ( )
162
+ . map ( |builtin_runner| ( builtin_runner. name ( ) , builtin_runner) )
163
+ . collect ( ) ;
164
+ for builtin in builtins {
165
+ if let Some ( builtin_runner) = runner_map. get ( & builtin) {
166
+ stack. append ( & mut builtin_runner. initial_stack ( ) ) ;
167
+ } else {
168
+ stack. push ( Felt252 :: ZERO . into ( ) )
169
+ }
170
+ }
171
+ }
172
+
173
+ fn initialize_builtin_runner_segments (
174
+ builtin_runners : & mut [ BuiltinRunner ] ,
175
+ segments : & mut MemorySegmentManager ,
176
+ ) {
177
+ for builtin_runner in builtin_runners. iter_mut ( ) {
178
+ builtin_runner. initialize_segments ( segments) ;
179
+ }
180
+
181
+ for builtin_runner in builtin_runners. iter_mut ( ) {
182
+ if let BuiltinRunner :: Mod ( mod_builtin_runner) = builtin_runner {
183
+ mod_builtin_runner. initialize_zero_segment ( segments) ;
184
+ }
185
+ }
186
+ }
187
+
180
188
// TODO: Remove this once cyclic dependency is fixed.
181
189
// It should not be necessary, but cargo treats executable BuiltinName as a separate type
182
190
// which is why I had to create this adapter function.
@@ -215,12 +223,14 @@ pub fn check_builtin_order(builtins: &[BuiltinName]) -> Result<(), RunnerError>
215
223
216
224
pub fn initialize_builtin_runners (
217
225
layout : & CairoLayout ,
218
- mut builtins : HashSet < BuiltinName > ,
226
+ builtins : & [ BuiltinName ] ,
219
227
allow_missing_builtins : bool ,
220
228
create_all_builtins : bool ,
221
229
) -> Result < Vec < BuiltinRunner > , RunnerError > {
222
230
let mut builtin_runners = Vec :: new ( ) ;
223
231
232
+ let mut builtins: HashSet < BuiltinName > = builtins. into_iter ( ) . map ( ToOwned :: to_owned) . collect ( ) ;
233
+
224
234
if layout. builtins . output {
225
235
let included = builtins. remove ( & BuiltinName :: output) ;
226
236
if included || create_all_builtins {
0 commit comments