@@ -70,7 +70,12 @@ pub fn get_maybe_relocatable_from_reference(
70
70
& hint_reference. ap_tracking_data ,
71
71
ap_tracking,
72
72
) ?;
73
- let mut val = offset1. add ( & offset2) . ok ( ) ?;
73
+ let mut val = match hint_reference. offset2 {
74
+ OffsetValue :: Reference ( _, _, _, true )
75
+ | OffsetValue :: Immediate ( _)
76
+ | OffsetValue :: Value ( _) => offset1. add ( & offset2) . ok ( ) ?,
77
+ OffsetValue :: Reference ( _, _, _, false ) => offset1. sub ( & offset2) . ok ( ) ?,
78
+ } ;
74
79
if hint_reference. inner_dereference && hint_reference. outer_dereference {
75
80
val = vm. get_maybe ( & val) ?;
76
81
}
@@ -139,7 +144,7 @@ fn get_offset_value(
139
144
match offset_value {
140
145
OffsetValue :: Immediate ( f) => Some ( f. into ( ) ) ,
141
146
OffsetValue :: Value ( v) => Some ( Felt252 :: from ( * v) . into ( ) ) ,
142
- OffsetValue :: Reference ( register, offset, deref) => {
147
+ OffsetValue :: Reference ( register, offset, deref, _ ) => {
143
148
let addr = ( if matches ! ( register, Register :: FP ) {
144
149
vm. get_fp ( )
145
150
} else {
@@ -176,7 +181,7 @@ mod tests {
176
181
// Reference: cast(2, felt)
177
182
let mut vm = vm ! ( ) ;
178
183
vm. segments = segments ! [ ( ( 1 , 0 ) , 0 ) ] ;
179
- let mut hint_ref = HintReference :: new ( 0 , 0 , false , false ) ;
184
+ let mut hint_ref = HintReference :: new ( 0 , 0 , false , false , true ) ;
180
185
hint_ref. offset1 = OffsetValue :: Immediate ( Felt252 :: from ( 2 ) ) ;
181
186
182
187
assert_eq ! (
@@ -191,8 +196,8 @@ mod tests {
191
196
fn get_offset_value_reference_valid ( ) {
192
197
let mut vm = vm ! ( ) ;
193
198
vm. segments = segments ! [ ( ( 1 , 0 ) , 0 ) ] ;
194
- let mut hint_ref = HintReference :: new ( 0 , 0 , false , true ) ;
195
- hint_ref. offset1 = OffsetValue :: Reference ( Register :: FP , 2_i32 , false ) ;
199
+ let mut hint_ref = HintReference :: new ( 0 , 0 , false , true , true ) ;
200
+ hint_ref. offset1 = OffsetValue :: Reference ( Register :: FP , 2_i32 , false , true ) ;
196
201
197
202
assert_matches ! (
198
203
get_offset_value( & vm, & hint_ref. offset1, & hint_ref. ap_tracking_data, & ApTracking :: new( ) ) ,
@@ -205,8 +210,8 @@ mod tests {
205
210
fn get_offset_value_invalid ( ) {
206
211
let mut vm = vm ! ( ) ;
207
212
vm. segments = segments ! [ ( ( 1 , 0 ) , 0 ) ] ;
208
- let mut hint_ref = HintReference :: new ( 0 , 0 , false , true ) ;
209
- hint_ref. offset1 = OffsetValue :: Reference ( Register :: FP , -2_i32 , false ) ;
213
+ let mut hint_ref = HintReference :: new ( 0 , 0 , false , true , true ) ;
214
+ hint_ref. offset1 = OffsetValue :: Reference ( Register :: FP , -2_i32 , false , true ) ;
210
215
211
216
assert_matches ! (
212
217
get_offset_value(
@@ -228,7 +233,7 @@ mod tests {
228
233
assert_matches ! (
229
234
get_ptr_from_reference(
230
235
& vm,
231
- & HintReference :: new( 0 , 0 , false , false ) ,
236
+ & HintReference :: new( 0 , 0 , false , false , true ) ,
232
237
& ApTracking :: new( )
233
238
) ,
234
239
Ok ( x) if x == relocatable!( 1 , 0 )
@@ -244,7 +249,7 @@ mod tests {
244
249
assert_matches ! (
245
250
get_ptr_from_reference(
246
251
& vm,
247
- & HintReference :: new( 0 , 0 , false , true ) ,
252
+ & HintReference :: new( 0 , 0 , false , true , true ) ,
248
253
& ApTracking :: new( )
249
254
) ,
250
255
Ok ( x) if x == relocatable!( 3 , 0 )
@@ -256,7 +261,7 @@ mod tests {
256
261
fn get_ptr_from_reference_with_dereference_and_imm ( ) {
257
262
let mut vm = vm ! ( ) ;
258
263
vm. segments = segments ! [ ( ( 1 , 0 ) , ( 4 , 0 ) ) ] ;
259
- let mut hint_ref = HintReference :: new ( 0 , 0 , true , false ) ;
264
+ let mut hint_ref = HintReference :: new ( 0 , 0 , true , false , true ) ;
260
265
hint_ref. offset2 = OffsetValue :: Value ( 2 ) ;
261
266
262
267
assert_matches ! (
@@ -270,7 +275,7 @@ mod tests {
270
275
fn compute_addr_from_reference_no_regiter_in_reference ( ) {
271
276
let mut vm = vm ! ( ) ;
272
277
vm. segments = segments ! [ ( ( 1 , 0 ) , ( 4 , 0 ) ) ] ;
273
- let mut hint_reference = HintReference :: new ( 0 , 0 , false , false ) ;
278
+ let mut hint_reference = HintReference :: new ( 0 , 0 , false , false , true ) ;
274
279
hint_reference. offset1 = OffsetValue :: Immediate ( Felt252 :: from ( 2_i32 ) ) ;
275
280
276
281
assert ! ( compute_addr_from_reference( & hint_reference, & vm, & ApTracking :: new( ) ) . is_none( ) ) ;
@@ -282,8 +287,8 @@ mod tests {
282
287
let mut vm = vm ! ( ) ;
283
288
vm. segments = segments ! [ ( ( 1 , 0 ) , 4 ) ] ;
284
289
// vm.run_context.fp = -1;
285
- let mut hint_reference = HintReference :: new ( 0 , 0 , false , false ) ;
286
- hint_reference. offset1 = OffsetValue :: Reference ( Register :: FP , -1 , true ) ;
290
+ let mut hint_reference = HintReference :: new ( 0 , 0 , false , false , true ) ;
291
+ hint_reference. offset1 = OffsetValue :: Reference ( Register :: FP , -1 , true , true ) ;
287
292
288
293
assert_matches ! (
289
294
compute_addr_from_reference( & hint_reference, & vm, & ApTracking :: new( ) ) ,
@@ -356,7 +361,7 @@ mod tests {
356
361
( ( 0 , 5 ) , 3 ) // [[[fp + 2] + 2]] -> [(0, 5)] -> 3
357
362
] ;
358
363
let hint_ref = HintReference {
359
- offset1 : OffsetValue :: Reference ( Register :: FP , 2 , true ) ,
364
+ offset1 : OffsetValue :: Reference ( Register :: FP , 2 , true , true ) ,
360
365
offset2 : OffsetValue :: Value ( 2 ) ,
361
366
outer_dereference : true ,
362
367
inner_dereference : true ,
@@ -381,7 +386,7 @@ mod tests {
381
386
] ;
382
387
// [fp + 4] + (-5) = 8 - 5 = 3
383
388
let hint_ref = HintReference {
384
- offset1 : OffsetValue :: Reference ( Register :: FP , 4 , true ) ,
389
+ offset1 : OffsetValue :: Reference ( Register :: FP , 4 , true , true ) ,
385
390
offset2 : OffsetValue :: Immediate ( Felt252 :: from ( -5 ) ) ,
386
391
outer_dereference : false ,
387
392
inner_dereference : false ,
0 commit comments