Repository: MystenLabs/sui
File: external-crates/move/crates/move-vm-runtime/src/natives/move_stdlib/vector.rs (Rust)

Code before:
}

/***************************************************************************************************
 * native fun push_back
 *
 *   gas cost: base_cost + legacy_unit_cost * max(1, size_of(val))
 *
 **************************************************************************************************/
#[derive(Debug, Clone)]
pub struct PushBackGasParameters {
    pub base: InternalGas,
    pub legacy_per_abstract_memory_unit: InternalGasPerAbstractMemoryUnit,
}

pub fn native_push_back(
    gas_params: &PushBackGasParameters,
    context: &mut NativeContext,
    ty_args: Vec<Type>,
    mut args: VecDeque<Value>,
) -> PartialVMResult<NativeResult> {
    debug_assert!(ty_args.len() == 1);
    debug_assert!(args.len() == 2);

    native_charge_gas_early_exit!(context, gas_params.base);

    let e = args.pop_back().unwrap();
    let r = pop_arg!(args, VectorRef);

    if gas_params.legacy_per_abstract_memory_unit != 0.into() {
        let cost = gas_params.legacy_per_abstract_memory_unit
            * std::cmp::max(
                e.abstract_memory_size(&SizeConfig {
                    traverse_references: false,
                    include_vector_size: false,
                }),
                1.into(),
            );
        native_charge_gas_early_exit!(context, cost);
    }

    NativeResult::map_partial_vm_result_empty(
        context.gas_used(),
        r.push_back(
            e,
            &ty_args[0],
            context.runtime_limits_config().vector_len_max,
        ),
    )
}

pub fn make_native_push_back(gas_params: PushBackGasParameters) -> NativeFunction {

Review comment (suggestion):
I think it may be nice to make a macro for this (something like `safe_pop!`/`checked_pop!` or something like that) as it will be good to have in general I think. 

Code after:
}

/***************************************************************************************************
 * native fun push_back
 *
 *   gas cost: base_cost + legacy_unit_cost * max(1, size_of(val))
 *
 **************************************************************************************************/
#[derive(Debug, Clone)]
pub struct PushBackGasParameters {
    pub base: InternalGas,
    pub legacy_per_abstract_memory_unit: InternalGasPerAbstractMemoryUnit,
}

pub fn native_push_back(
    gas_params: &PushBackGasParameters,
    context: &mut NativeContext,
    ty_args: Vec<Type>,
    mut args: VecDeque<Value>,
) -> PartialVMResult<NativeResult> {
    debug_assert!(ty_args.len() == 1);
    debug_assert!(args.len() == 2);

    native_charge_gas_early_exit!(context, gas_params.base);

    let Some(e) = args.pop_back() else {
        return Err(PartialVMError::new(StatusCode::VECTOR_OPERATION_ERROR)
            .with_message("Internal error: missing argument in native push_back".to_string()));
    };

    let r = pop_arg!(args, VectorRef);

    if gas_params.legacy_per_abstract_memory_unit != 0.into() {
        let cost = gas_params.legacy_per_abstract_memory_unit
            * std::cmp::max(
                e.abstract_memory_size(&SizeConfig {
                    traverse_references: false,
                    include_vector_size: false,
                }),
                1.into(),
            );
        native_charge_gas_early_exit!(context, cost);
    }

    NativeResult::map_partial_vm_result_empty(
        context.gas_used(),
        r.push_back(
            e,
            &ty_args[0],
            context.runtime_limits_config().vector_len_max,
        ),