pub fn apply(ctx: &mut Context,
             curr_p: &mut Process,
             fail_label: LTerm,
             target: CallBifTarget,
             args: &[LTerm],
             dst: LTerm,
             gc: bool) -> DispatchResult
{
  let maybe_bif_fn =
    match target {
      CallBifTarget::ImportTerm(ho_imp) =>
        callbif_resolve_import(ho_imp),

      CallBifTarget::MFArity(mfa) => callbif_resolve_mfa(&mfa),

      CallBifTarget::ImportPointer(ho_imp_ptr) => {
        match unsafe { (*ho_imp_ptr).resolve_bif() } {
          Ok(fn_ptr) => BifResolutionResult::FnPointer(fn_ptr),
          Err(e) => BifResolutionResult::Fail(e),
        }
      },

      CallBifTarget::BifFnPointer(fn_ptr) =>
        BifResolutionResult::FnPointer(fn_ptr),
    };

  // Now having resolved the bif function, let's call it

  let bif_result = match maybe_bif_fn {
    BifResolutionResult::FnPointer(fn_ptr) =>
      callbif_apply_bif(ctx, curr_p, fn_ptr, args),

    BifResolutionResult::BadfunError(badfun_val) =>
      return DispatchResult::badfun_val(badfun_val, &mut curr_p.heap),

    BifResolutionResult::Fail(e) => return callbif_handle_fail(&e),
  };

  // Now having called the function let's see if there was some good result or
  // an error occured

  println!("call_bif a={} gc={} call result {}", args.len(), gc, bif_result);

  match bif_result {
    // On error and if fail label is a CP, perform a goto
    // Assume that error is already written to `reason` in process
    BifResult::Exception(ex_type, ex_reason) => {
      if fail_label.is_cp() {
        ctx.ip = CodePtr::from_cp(fail_label)
      }
      // Set exception via dispatchresult
      DispatchResult::Error(ex_type, ex_reason)
    },

    BifResult::Fail(f) =>
      callbif_handle_fail(&f),

    BifResult::Value(val) => {
      // if dst is not NIL, store the result in it
      if !dst.is_nil() {
        ctx.store(val, dst, &mut curr_p.heap)
      }
      DispatchResult::Normal
    },
  }
}
/// Generic bif0,1,2 application. Bif0 cannot have a fail label but bif1 and
/// bif2 can, so on exception a jump will be performed.
///
/// Args:
///   `curr_p` - the process which is running;
///   `target` - the term pointing to a callable;
///   `fail_label` - if not NIL, we suppress a possible exception and jump there;
///   `args` - the arguments;
///   `dst` - register where the result will go;
///   `gc` if gc is allowed then `ctx.live` will be used as live.
//#[inline]
// Inline to allow const folding optimization
Generic bif0,1,2 application. Bif0 cannot have a fail label but bif1 and
bif2 can, so on exception a jump will be performed.


Generic bif0 1 2 application . Bif0 cannot have a fail label but bif1 and bif2 can so on exception a jump will be performed .
pub fn apply(ctx: &mut Context,
             curr_p: &mut Process,
             fail_label: LTerm,
             target: CallBifTarget,
             args: &[LTerm],
             dst: LTerm,
             gc: bool) -> DispatchResult
{
  let maybe_bif_fn =
    match target {
      CallBifTarget::ImportTerm(ho_imp) =>
        callbif_resolve_import(ho_imp),
      CallBifTarget::MFArity(mfa) => callbif_resolve_mfa(&mfa),
      CallBifTarget::ImportPointer(ho_imp_ptr) => {
        match unsafe { (*ho_imp_ptr).resolve_bif() } {
          Ok(fn_ptr) => BifResolutionResult::FnPointer(fn_ptr),
          Err(e) => BifResolutionResult::Fail(e),
        }
      },
      CallBifTarget::BifFnPointer(fn_ptr) =>
        BifResolutionResult::FnPointer(fn_ptr),
    };
  // Now having resolved the bif function, let's call it
  let bif_result = match maybe_bif_fn {
    BifResolutionResult::FnPointer(fn_ptr) =>
      callbif_apply_bif(ctx, curr_p, fn_ptr, args),
    BifResolutionResult::BadfunError(badfun_val) =>
      return DispatchResult::badfun_val(badfun_val, &mut curr_p.heap),
    BifResolutionResult::Fail(e) => return callbif_handle_fail(&e),
  };
  // Now having called the function let's see if there was some good result or
  // an error occured
  println!("call_bif a={} gc={} call result {}", args.len(), gc, bif_result);
  match bif_result {
    // On error and if fail label is a CP, perform a goto
    // Assume that error is already written to `reason` in process
    BifResult::Exception(ex_type, ex_reason) => {
      if fail_label.is_cp() {
        ctx.ip = CodePtr::from_cp(fail_label)
      }
      // Set exception via dispatchresult
      DispatchResult::Error(ex_type, ex_reason)
    },
    BifResult::Fail(f) =>
      callbif_handle_fail(&f),
    BifResult::Value(val) => {
      // if dst is not NIL, store the result in it
      if !dst.is_nil() {
        ctx.store(val, dst, &mut curr_p.heap)
      }
      DispatchResult::Normal
    },
  }
}
pub fn apply ( ctx : & mut Context , curr_p : & mut Process , fail_label : LTerm , target : CallBifTarget , args : & [ LTerm ] , dst : LTerm , gc : bool ) -> DispatchResult { let maybe_bif_fn = match target { CallBifTarget :: ImportTerm ( ho_imp ) => callbif_resolve_import ( ho_imp ) , CallBifTarget :: MFArity ( mfa ) => callbif_resolve_mfa ( & mfa ) , CallBifTarget :: ImportPointer ( ho_imp_ptr ) => { match unsafe { ( * ho_imp_ptr ) . resolve_bif ( ) } { Ok ( fn_ptr ) => BifResolutionResult :: FnPointer ( fn_ptr ) , Err ( e ) => BifResolutionResult :: Fail ( e ) , } } , CallBifTarget :: BifFnPointer ( fn_ptr ) => BifResolutionResult :: FnPointer ( fn_ptr ) , } ; // Now having resolved the bif function, let's call it let bif_result = match maybe_bif_fn { BifResolutionResult :: FnPointer ( fn_ptr ) => callbif_apply_bif ( ctx , curr_p , fn_ptr , args ) , BifResolutionResult :: BadfunError ( badfun_val ) => return DispatchResult :: badfun_val ( badfun_val , & mut curr_p . heap ) , BifResolutionResult :: Fail ( e ) => return callbif_handle_fail ( & e ) , } ; // Now having called the function let's see if there was some good result or // an error occured println ! ( " " args len ( ) gc bif_result ) ; match bif_result { // On error and if fail label is a CP, perform a goto // Assume that error is already written to `reason` in process BifResult :: Exception ( ex_type , ex_reason ) => { if fail_label . is_cp ( ) { ctx . ip = CodePtr :: from_cp ( fail_label ) } // Set exception via dispatchresult DispatchResult :: Error ( ex_type , ex_reason ) } , BifResult :: Fail ( f ) => callbif_handle_fail ( & f ) , BifResult :: Value ( val ) => { // if dst is not NIL, store the result in it if ! dst . is_nil ( ) { ctx . store ( val , dst , & mut curr_p . heap ) } DispatchResult :: Normal } , } }
Generic bif0,1,2 application.
Generic bif0 1 2 application .
ctx
&mut Context
curr_p
&mut Process
fail_label
LTerm
target
CallBifTarget
args
&[LTerm]
dst
LTerm
gc
bool
[inline]
Inline to allow const folding optimization
Inline to allow const folding optimization