fn ic0_call_perform(&mut self) -> HypervisorResult<i32> {
        match &mut self.api_type {
            ApiType::Start { .. }
            | ApiType::Init { .. }
            | ApiType::ReplicatedQuery { .. }
            | ApiType::NonReplicatedQuery {
                query_kind: NonReplicatedQueryKind::Pure,
                ..
            }
            | ApiType::Cleanup { .. }
            | ApiType::PreUpgrade { .. }
            | ApiType::InspectMessage { .. } => Err(self.error_for("ic0_call_perform")),
            ApiType::Update {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            }
            | ApiType::Heartbeat {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            }
            | ApiType::ReplyCallback {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            }
            | ApiType::RejectCallback {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            } => {
                let req_in_prep = outgoing_request.take().ok_or_else(|| {
                    ContractViolation(
                        "ic0.call_perform called when no call is under construction.".to_string(),
                    )
                })?;

                let req = into_request(
                    routing_table,
                    subnet_records,
                    req_in_prep,
                    *call_context_id,
                    *own_subnet_id,
                    *own_subnet_type,
                    &self.system_state_accessor,
                    &self.log,
                )?;
                self.push_output_request(req)
            }
            ApiType::NonReplicatedQuery {
                call_context_id,
                own_subnet_id,
                outgoing_request,
                routing_table,
                query_kind: NonReplicatedQueryKind::Stateful,
                ..
            } => {
                let req_in_prep = outgoing_request.take().ok_or_else(|| {
                    ContractViolation(
                        "ic0.call_perform called when no call is under construction.".to_string(),
                    )
                })?;

                // We do not support inter canister queries between subnets so
                // we can use nominal values for these fields to satisfy the
                // constraints.
                let own_subnet_type = SubnetType::Application;
                let mut subnet_records = BTreeMap::new();
                subnet_records.insert(*own_subnet_id, own_subnet_type);

                let req = into_request(
                    routing_table,
                    &subnet_records,
                    req_in_prep,
                    *call_context_id,
                    *own_subnet_id,
                    own_subnet_type,
                    &self.system_state_accessor,
                    &self.log,
                )?;
                self.push_output_request(req)
            }
        }
    }
// Note that if this function returns an error, then the canister will be
// trapped and the state will be rolled back. Hence, we do not have to worry
// about rolling back any modifications that previous calls like
// ic0_call_cycles_add128() made.
//
// However, this call can still "fail" without returning an error. Examples
// are if the canister does not have sufficient cycles to send the request
// or the output queues are full. In this case, we need to perform the
// necessary cleanups.
Note that if this function returns an error, then the canister will be
trapped and the state will be rolled back. Hence, we do not have to worry
about rolling back any modifications that previous calls like
ic0_call_cycles_add128() made.

However, this call can still "fail" without returning an error. Examples
are if the canister does not have sufficient cycles to send the request
or the output queues are full. In this case, we need to perform the
necessary cleanups.
Note that if this function returns an error then the canister will be trapped and the state will be rolled back . Hence we do not have to worry about rolling back any modifications that previous calls like ic0_call_cycles_add128 () made . However this call can still " fail " without returning an error . Examples are if the canister does not have sufficient cycles to send the request or the output queues are full . In this case we need to perform the necessary cleanups .
fn ic0_call_perform(&mut self) -> HypervisorResult<i32> {
        match &mut self.api_type {
            ApiType::Start { .. }
            | ApiType::Init { .. }
            | ApiType::ReplicatedQuery { .. }
            | ApiType::NonReplicatedQuery {
                query_kind: NonReplicatedQueryKind::Pure,
                ..
            }
            | ApiType::Cleanup { .. }
            | ApiType::PreUpgrade { .. }
            | ApiType::InspectMessage { .. } => Err(self.error_for("ic0_call_perform")),
            ApiType::Update {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            }
            | ApiType::Heartbeat {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            }
            | ApiType::ReplyCallback {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            }
            | ApiType::RejectCallback {
                call_context_id,
                own_subnet_id,
                own_subnet_type,
                outgoing_request,
                routing_table,
                subnet_records,
                ..
            } => {
                let req_in_prep = outgoing_request.take().ok_or_else(|| {
                    ContractViolation(
                        "ic0.call_perform called when no call is under construction.".to_string(),
                    )
                })?;
                let req = into_request(
                    routing_table,
                    subnet_records,
                    req_in_prep,
                    *call_context_id,
                    *own_subnet_id,
                    *own_subnet_type,
                    &self.system_state_accessor,
                    &self.log,
                )?;
                self.push_output_request(req)
            }
            ApiType::NonReplicatedQuery {
                call_context_id,
                own_subnet_id,
                outgoing_request,
                routing_table,
                query_kind: NonReplicatedQueryKind::Stateful,
                ..
            } => {
                let req_in_prep = outgoing_request.take().ok_or_else(|| {
                    ContractViolation(
                        "ic0.call_perform called when no call is under construction.".to_string(),
                    )
                })?;
                // We do not support inter canister queries between subnets so
                // we can use nominal values for these fields to satisfy the
                // constraints.
                let own_subnet_type = SubnetType::Application;
                let mut subnet_records = BTreeMap::new();
                subnet_records.insert(*own_subnet_id, own_subnet_type);
                let req = into_request(
                    routing_table,
                    &subnet_records,
                    req_in_prep,
                    *call_context_id,
                    *own_subnet_id,
                    own_subnet_type,
                    &self.system_state_accessor,
                    &self.log,
                )?;
                self.push_output_request(req)
            }
        }
    }
fn ic0_call_perform ( & mut self ) -> HypervisorResult < i32 > { match & mut self . api_type { ApiType :: Start { .. } | ApiType :: Init { .. } | ApiType :: ReplicatedQuery { .. } | ApiType :: NonReplicatedQuery { query_kind : NonReplicatedQueryKind :: Pure , .. } | ApiType :: Cleanup { .. } | ApiType :: PreUpgrade { .. } | ApiType :: InspectMessage { .. } => Err ( self . error_for ( " " ) ) , ApiType :: Update { call_context_id , own_subnet_id , own_subnet_type , outgoing_request , routing_table , subnet_records , .. } | ApiType :: Heartbeat { call_context_id , own_subnet_id , own_subnet_type , outgoing_request , routing_table , subnet_records , .. } | ApiType :: ReplyCallback { call_context_id , own_subnet_id , own_subnet_type , outgoing_request , routing_table , subnet_records , .. } | ApiType :: RejectCallback { call_context_id , own_subnet_id , own_subnet_type , outgoing_request , routing_table , subnet_records , .. } => { let req_in_prep = outgoing_request . take ( ) . ok_or_else ( | | { ContractViolation ( " " . to_string ( ) , ) } ) ? ; let req = into_request ( routing_table , subnet_records , req_in_prep , * call_context_id , * own_subnet_id , * own_subnet_type , & self . system_state_accessor , & self . log , ) ? ; self . push_output_request ( req ) } ApiType :: NonReplicatedQuery { call_context_id , own_subnet_id , outgoing_request , routing_table , query_kind : NonReplicatedQueryKind :: Stateful , .. } => { let req_in_prep = outgoing_request . take ( ) . ok_or_else ( | | { ContractViolation ( " " . to_string ( ) , ) } ) ? ; // We do not support inter canister queries between subnets so // we can use nominal values for these fields to satisfy the // constraints. let own_subnet_type = SubnetType :: Application ; let mut subnet_records = BTreeMap :: new ( ) ; subnet_records . insert ( * own_subnet_id , own_subnet_type ) ; let req = into_request ( routing_table , & subnet_records , req_in_prep , * call_context_id , * own_subnet_id , own_subnet_type , & self . system_state_accessor , & self . log , ) ? ; self . push_output_request ( req ) } } }
Note that if this function returns an error, then the canister will be
trapped and the state will be rolled back.
Note that if this function returns an error then the canister will be trapped and the state will be rolled back .
&mut self
&mut self