Repository: aptos-labs/aptos-core
File: third_party/move/move-vm/runtime/src/interpreter.rs (Rust)

Code before:
                    arg_tys.push_front(expected_ty.clone())
                }
            }
        }

        let native_function = function.get_native()?;

        gas_meter.charge_native_function_before_execution(
            ty_args.iter().map(|ty| TypeWithRuntimeEnvironment {
                ty,
                runtime_environment: self.loader.runtime_environment(),
            }),
            args.iter(),
        )?;

        let mut native_context = NativeContext::new(
            self,
            data_cache,
            self.loader.unmetered_module_storage(),
            extensions,
            gas_meter,
            traversal_context,
        );

        // Capture stack sizes before the call for later validation.
        let saved_value_stack_size = self.operand_stack.value.len();
        let saved_type_stack_size = self.operand_stack.types.len();

        let result = native_function(&mut native_context, ty_args, args)?;

        // Note(Gas): The order by which gas is charged / error gets returned MUST NOT be modified
        //            here or otherwise it becomes an incompatible change!!!
        match result {
            NativeResult::Success {
                cost,
                ret_vals: return_values,
            } => {
                gas_meter.charge_native_function(cost, Some(return_values.iter()))?;
                // Paranoid check to protect us against incorrect native function implementations. A native function that
                // returns a different number of values than its declared types will trigger this check.
                if return_values.len() != function.return_tys().len() {
                    return Err(PartialVMError::new_invariant_violation(
                        "Arity mismatch: return value count does not match return type count",
                    ));
                }
                // Put return values on the top of the operand stack, where the caller will find them.
                // This is one of only two times the operand stack is shared across call stack frames; the other is in handling
                // the Return instruction for normal calls
                for value in return_values {
                    self.operand_stack.push(value)?;
                }

Review comment (suggestion):

```suggestion
        let pre_native_call_value_stack_size = self.operand_stack.value.len();
```

Code after:
                    arg_tys.push_front(expected_ty.clone())
                }
            }
        }

        let native_function = function.get_native()?;

        gas_meter.charge_native_function_before_execution(
            ty_args.iter().map(|ty| TypeWithRuntimeEnvironment {
                ty,
                runtime_environment: self.loader.runtime_environment(),
            }),
            args.iter(),
        )?;

        let mut native_context = NativeContext::new(
            self,
            data_cache,
            self.loader.unmetered_module_storage(),
            extensions,
            gas_meter,
            traversal_context,
        );

        // Capture stack sizes before the call for later validation.
        let pre_native_call_value_stack_size = self.operand_stack.value.len();
        let pre_native_call_type_stack_size = self.operand_stack.types.len();

        let result = native_function(&mut native_context, ty_args, args)?;

        // Note(Gas): The order by which gas is charged / error gets returned MUST NOT be modified
        //            here or otherwise it becomes an incompatible change!!!
        match result {
            NativeResult::Success {
                cost,
                ret_vals: return_values,
            } => {
                gas_meter.charge_native_function(cost, Some(return_values.iter()))?;
                // Paranoid check to protect us against incorrect native function implementations. A native function that
                // returns a different number of values than its declared types will trigger this check.
                if return_values.len() != function.return_tys().len() {
                    return Err(PartialVMError::new_invariant_violation(
                        "Arity mismatch: return value count does not match return type count",
                    ));
                }
                // Put return values on the top of the operand stack, where the caller will find them.
                // This is one of only two times the operand stack is shared across call stack frames; the other is in handling
                // the Return instruction for normal calls
                for value in return_values {
                    self.operand_stack.push(value)?;
                }