@@ -18,8 +18,9 @@ use move_core_types::{
1818 vm_status:: StatusCode ,
1919} ;
2020use move_vm_runtime:: {
21- native_functions,
21+ native_charge_gas_early_exit , native_functions,
2222 native_functions:: { NativeContext , NativeFunction , NativeFunctionTable } ,
23+ native_gas_total_cost,
2324} ;
2425use move_vm_types:: {
2526 loaded_data:: runtime_types:: Type ,
@@ -350,6 +351,9 @@ fn native_new_table_handle(
350351 assert_eq ! ( ty_args. len( ) , 2 ) ;
351352 assert ! ( args. is_empty( ) ) ;
352353
354+ let mut gas_left = context. gas_budget ( ) ;
355+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
356+
353357 let table_context = context. extensions ( ) . get :: < NativeTableContext > ( ) ;
354358 let mut table_data = table_context. table_data . borrow_mut ( ) ;
355359
@@ -371,7 +375,7 @@ fn native_new_table_handle(
371375 . is_none( ) ) ;
372376
373377 Ok ( NativeResult :: ok (
374- gas_params . base ,
378+ native_gas_total_cost ! ( context , gas_left ) ,
375379 smallvec ! [ Value :: address( handle) ] ,
376380 ) )
377381}
@@ -399,6 +403,8 @@ fn native_add_box(
399403) -> PartialVMResult < NativeResult > {
400404 assert_eq ! ( ty_args. len( ) , 3 ) ;
401405 assert_eq ! ( args. len( ) , 3 ) ;
406+ let mut gas_left = context. gas_budget ( ) ;
407+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
402408
403409 let table_context = context. extensions ( ) . get :: < NativeTableContext > ( ) ;
404410 let mut table_data = table_context. table_data . borrow_mut ( ) ;
@@ -407,19 +413,31 @@ fn native_add_box(
407413 let key = args. pop_back ( ) . unwrap ( ) ;
408414 let handle = get_table_handle ( & pop_arg ! ( args, StructRef ) ) ?;
409415
410- let mut cost = gas_params. base ;
411-
412416 let table = table_data. get_or_create_table ( context, handle, & ty_args[ 0 ] , & ty_args[ 2 ] ) ?;
413417
414418 let key_bytes = serialize ( & table. key_layout , & key) ?;
415- cost += gas_params. per_byte_serialized * NumBytes :: new ( key_bytes. len ( ) as u64 ) ;
419+ native_charge_gas_early_exit ! (
420+ context,
421+ gas_left,
422+ gas_params. per_byte_serialized * NumBytes :: new( key_bytes. len( ) as u64 )
423+ ) ;
416424
417425 let ( gv, loaded) = table. get_or_create_global_value ( table_context, key_bytes) ?;
418- cost += common_gas_params. calculate_load_cost ( loaded) ;
426+ native_charge_gas_early_exit ! (
427+ context,
428+ gas_left,
429+ common_gas_params. calculate_load_cost( loaded)
430+ ) ;
419431
420432 match gv. move_to ( val) {
421- Ok ( _) => Ok ( NativeResult :: ok ( cost, smallvec ! [ ] ) ) ,
422- Err ( _) => Ok ( NativeResult :: err ( cost, ALREADY_EXISTS ) ) ,
433+ Ok ( _) => Ok ( NativeResult :: ok (
434+ native_gas_total_cost ! ( context, gas_left) ,
435+ smallvec ! [ ] ,
436+ ) ) ,
437+ Err ( _) => Ok ( NativeResult :: err (
438+ native_gas_total_cost ! ( context, gas_left) ,
439+ ALREADY_EXISTS ,
440+ ) ) ,
423441 }
424442}
425443
@@ -450,6 +468,9 @@ fn native_borrow_box(
450468 assert_eq ! ( ty_args. len( ) , 3 ) ;
451469 assert_eq ! ( args. len( ) , 2 ) ;
452470
471+ let mut gas_left = context. gas_budget ( ) ;
472+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
473+
453474 let table_context = context. extensions ( ) . get :: < NativeTableContext > ( ) ;
454475 let mut table_data = table_context. table_data . borrow_mut ( ) ;
455476
@@ -458,17 +479,29 @@ fn native_borrow_box(
458479
459480 let table = table_data. get_or_create_table ( context, handle, & ty_args[ 0 ] , & ty_args[ 2 ] ) ?;
460481
461- let mut cost = gas_params. base ;
462-
463482 let key_bytes = serialize ( & table. key_layout , & key) ?;
464- cost += gas_params. per_byte_serialized * NumBytes :: new ( key_bytes. len ( ) as u64 ) ;
483+ native_charge_gas_early_exit ! (
484+ context,
485+ gas_left,
486+ gas_params. per_byte_serialized * NumBytes :: new( key_bytes. len( ) as u64 )
487+ ) ;
465488
466489 let ( gv, loaded) = table. get_or_create_global_value ( table_context, key_bytes) ?;
467- cost += common_gas_params. calculate_load_cost ( loaded) ;
490+ native_charge_gas_early_exit ! (
491+ context,
492+ gas_left,
493+ common_gas_params. calculate_load_cost( loaded)
494+ ) ;
468495
469496 match gv. borrow_global ( ) {
470- Ok ( ref_val) => Ok ( NativeResult :: ok ( cost, smallvec ! [ ref_val] ) ) ,
471- Err ( _) => Ok ( NativeResult :: err ( cost, NOT_FOUND ) ) ,
497+ Ok ( ref_val) => Ok ( NativeResult :: ok (
498+ native_gas_total_cost ! ( context, gas_left) ,
499+ smallvec ! [ ref_val] ,
500+ ) ) ,
501+ Err ( _) => Ok ( NativeResult :: err (
502+ native_gas_total_cost ! ( context, gas_left) ,
503+ NOT_FOUND ,
504+ ) ) ,
472505 }
473506}
474507
@@ -499,6 +532,9 @@ fn native_contains_box(
499532 assert_eq ! ( ty_args. len( ) , 3 ) ;
500533 assert_eq ! ( args. len( ) , 2 ) ;
501534
535+ let mut gas_left = context. gas_budget ( ) ;
536+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
537+
502538 let table_context = context. extensions ( ) . get :: < NativeTableContext > ( ) ;
503539 let mut table_data = table_context. table_data . borrow_mut ( ) ;
504540
@@ -507,17 +543,26 @@ fn native_contains_box(
507543
508544 let table = table_data. get_or_create_table ( context, handle, & ty_args[ 0 ] , & ty_args[ 2 ] ) ?;
509545
510- let mut cost = gas_params. base ;
511-
512546 let key_bytes = serialize ( & table. key_layout , & key) ?;
513- cost += gas_params. per_byte_serialized * NumBytes :: new ( key_bytes. len ( ) as u64 ) ;
547+ native_charge_gas_early_exit ! (
548+ context,
549+ gas_left,
550+ gas_params. per_byte_serialized * NumBytes :: new( key_bytes. len( ) as u64 )
551+ ) ;
514552
515553 let ( gv, loaded) = table. get_or_create_global_value ( table_context, key_bytes) ?;
516- cost += common_gas_params. calculate_load_cost ( loaded) ;
554+ native_charge_gas_early_exit ! (
555+ context,
556+ gas_left,
557+ common_gas_params. calculate_load_cost( loaded)
558+ ) ;
517559
518560 let exists = Value :: bool ( gv. exists ( ) ?) ;
519561
520- Ok ( NativeResult :: ok ( cost, smallvec ! [ exists] ) )
562+ Ok ( NativeResult :: ok (
563+ native_gas_total_cost ! ( context, gas_left) ,
564+ smallvec ! [ exists] ,
565+ ) )
521566}
522567
523568pub fn make_native_contains_box (
@@ -547,6 +592,9 @@ fn native_remove_box(
547592 assert_eq ! ( ty_args. len( ) , 3 ) ;
548593 assert_eq ! ( args. len( ) , 2 ) ;
549594
595+ let mut gas_left = context. gas_budget ( ) ;
596+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
597+
550598 let table_context = context. extensions ( ) . get :: < NativeTableContext > ( ) ;
551599 let mut table_data = table_context. table_data . borrow_mut ( ) ;
552600
@@ -555,17 +603,29 @@ fn native_remove_box(
555603
556604 let table = table_data. get_or_create_table ( context, handle, & ty_args[ 0 ] , & ty_args[ 2 ] ) ?;
557605
558- let mut cost = gas_params. base ;
559-
560606 let key_bytes = serialize ( & table. key_layout , & key) ?;
561- cost += gas_params. per_byte_serialized * NumBytes :: new ( key_bytes. len ( ) as u64 ) ;
607+ native_charge_gas_early_exit ! (
608+ context,
609+ gas_left,
610+ gas_params. per_byte_serialized * NumBytes :: new( key_bytes. len( ) as u64 )
611+ ) ;
562612
563613 let ( gv, loaded) = table. get_or_create_global_value ( table_context, key_bytes) ?;
564- cost += common_gas_params. calculate_load_cost ( loaded) ;
614+ native_charge_gas_early_exit ! (
615+ context,
616+ gas_left,
617+ common_gas_params. calculate_load_cost( loaded)
618+ ) ;
565619
566620 match gv. move_from ( ) {
567- Ok ( val) => Ok ( NativeResult :: ok ( cost, smallvec ! [ val] ) ) ,
568- Err ( _) => Ok ( NativeResult :: err ( cost, NOT_FOUND ) ) ,
621+ Ok ( val) => Ok ( NativeResult :: ok (
622+ native_gas_total_cost ! ( context, gas_left) ,
623+ smallvec ! [ val] ,
624+ ) ) ,
625+ Err ( _) => Ok ( NativeResult :: err (
626+ native_gas_total_cost ! ( context, gas_left) ,
627+ NOT_FOUND ,
628+ ) ) ,
569629 }
570630}
571631
@@ -594,6 +654,8 @@ fn native_destroy_empty_box(
594654 assert_eq ! ( ty_args. len( ) , 3 ) ;
595655 assert_eq ! ( args. len( ) , 1 ) ;
596656
657+ let mut gas_left = context. gas_budget ( ) ;
658+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
597659 let table_context = context. extensions ( ) . get :: < NativeTableContext > ( ) ;
598660 let mut table_data = table_context. table_data . borrow_mut ( ) ;
599661
@@ -603,7 +665,10 @@ fn native_destroy_empty_box(
603665
604666 assert ! ( table_data. removed_tables. insert( handle) ) ;
605667
606- Ok ( NativeResult :: ok ( gas_params. base , smallvec ! [ ] ) )
668+ Ok ( NativeResult :: ok (
669+ native_gas_total_cost ! ( context, gas_left) ,
670+ smallvec ! [ ] ,
671+ ) )
607672}
608673
609674pub fn make_native_destroy_empty_box ( gas_params : DestroyEmptyBoxGasParameters ) -> NativeFunction {
@@ -621,14 +686,20 @@ pub struct DropUncheckedBoxGasParameters {
621686
622687fn native_drop_unchecked_box (
623688 gas_params : & DropUncheckedBoxGasParameters ,
624- _context : & mut NativeContext ,
689+ context : & mut NativeContext ,
625690 ty_args : Vec < Type > ,
626691 args : VecDeque < Value > ,
627692) -> PartialVMResult < NativeResult > {
628693 assert_eq ! ( ty_args. len( ) , 3 ) ;
629694 assert_eq ! ( args. len( ) , 1 ) ;
630695
631- Ok ( NativeResult :: ok ( gas_params. base , smallvec ! [ ] ) )
696+ let mut gas_left = context. gas_budget ( ) ;
697+ native_charge_gas_early_exit ! ( context, gas_left, gas_params. base) ;
698+
699+ Ok ( NativeResult :: ok (
700+ native_gas_total_cost ! ( context, gas_left) ,
701+ smallvec ! [ ] ,
702+ ) )
632703}
633704
634705pub fn make_native_drop_unchecked_box ( gas_params : DropUncheckedBoxGasParameters ) -> NativeFunction {
0 commit comments