async fn do_trace(
    out: &mut StandardStream,
    execution: &mut VmExecution,
    sources: &rune::Sources,
    dump_stack: bool,
    with_source: bool,
) -> Result<Value, TraceError> {
    let mut current_frame_len = execution
        .vm()
        .map_err(TraceError::VmError)?
        .call_frames()
        .len();

    loop {
        {
            let vm = execution.vm().map_err(TraceError::VmError)?;
            let mut out = out.lock();

            if let Some((hash, signature)) =
                vm.unit().debug_info().and_then(|d| d.function_at(vm.ip()))
            {
                writeln!(out, "fn {} ({}):", signature, hash)?;
            }

            let debug = vm
                .unit()
                .debug_info()
                .and_then(|d| d.instruction_at(vm.ip()));

            if with_source {
                let debug_info = debug.and_then(|d| sources.get(d.source_id).map(|s| (s, d.span)));
                if let Some((source, span)) = debug_info {
                    source.emit_source_line(&mut out, span)?;
                }
            }

            if let Some(label) = debug.and_then(|d| d.label.as_ref()) {
                writeln!(out, "{}:", label)?;
            }

            if let Some(inst) = vm.unit().instruction_at(vm.ip()) {
                write!(out, "  {:04} = {}", vm.ip(), inst)?;
            } else {
                write!(out, "  {:04} = *out of bounds*", vm.ip())?;
            }

            if let Some(comment) = debug.and_then(|d| d.comment.as_ref()) {
                write!(out, " // {}", comment)?;
            }

            writeln!(out)?;
        }

        let result = match execution.async_step().await {
            Ok(result) => result,
            Err(e) => return Err(TraceError::VmError(e)),
        };

        let mut out = out.lock();

        if dump_stack {
            let vm = execution.vm().map_err(TraceError::VmError)?;
            let frames = vm.call_frames();

            let stack = vm.stack();

            if current_frame_len != frames.len() {
                if current_frame_len < frames.len() {
                    writeln!(out, "=> frame {} ({}):", frames.len(), stack.stack_bottom())?;
                } else {
                    writeln!(out, "<= frame {} ({}):", frames.len(), stack.stack_bottom())?;
                }

                current_frame_len = frames.len();
            }

            let values = stack.get(stack.stack_bottom()..).expect("bad stack slice");

            if values.is_empty() {
                writeln!(out, "    *empty*")?;
            }

            for (n, value) in values.iter().enumerate() {
                writeln!(out, "    {}+{} = {:?}", stack.stack_bottom(), n, value)?;
            }
        }

        if let Some(result) = result {
            break Ok(result);
        }
    }
}
/// Perform a detailed trace of the program.
Perform a detailed trace of the program.
Perform a detailed trace of the program .
async fn do_trace(
    out: &mut StandardStream,
    execution: &mut VmExecution,
    sources: &rune::Sources,
    dump_stack: bool,
    with_source: bool,
) -> Result<Value, TraceError> {
    let mut current_frame_len = execution
        .vm()
        .map_err(TraceError::VmError)?
        .call_frames()
        .len();
    loop {
        {
            let vm = execution.vm().map_err(TraceError::VmError)?;
            let mut out = out.lock();
            if let Some((hash, signature)) =
                vm.unit().debug_info().and_then(|d| d.function_at(vm.ip()))
            {
                writeln!(out, "fn {} ({}):", signature, hash)?;
            }
            let debug = vm
                .unit()
                .debug_info()
                .and_then(|d| d.instruction_at(vm.ip()));
            if with_source {
                let debug_info = debug.and_then(|d| sources.get(d.source_id).map(|s| (s, d.span)));
                if let Some((source, span)) = debug_info {
                    source.emit_source_line(&mut out, span)?;
                }
            }
            if let Some(label) = debug.and_then(|d| d.label.as_ref()) {
                writeln!(out, "{}:", label)?;
            }
            if let Some(inst) = vm.unit().instruction_at(vm.ip()) {
                write!(out, "  {:04} = {}", vm.ip(), inst)?;
            } else {
                write!(out, "  {:04} = *out of bounds*", vm.ip())?;
            }
            if let Some(comment) = debug.and_then(|d| d.comment.as_ref()) {
                write!(out, " // {}", comment)?;
            }
            writeln!(out)?;
        }
        let result = match execution.async_step().await {
            Ok(result) => result,
            Err(e) => return Err(TraceError::VmError(e)),
        };
        let mut out = out.lock();
        if dump_stack {
            let vm = execution.vm().map_err(TraceError::VmError)?;
            let frames = vm.call_frames();
            let stack = vm.stack();
            if current_frame_len != frames.len() {
                if current_frame_len < frames.len() {
                    writeln!(out, "=> frame {} ({}):", frames.len(), stack.stack_bottom())?;
                } else {
                    writeln!(out, "<= frame {} ({}):", frames.len(), stack.stack_bottom())?;
                }
                current_frame_len = frames.len();
            }
            let values = stack.get(stack.stack_bottom()..).expect("bad stack slice");
            if values.is_empty() {
                writeln!(out, "    *empty*")?;
            }
            for (n, value) in values.iter().enumerate() {
                writeln!(out, "    {}+{} = {:?}", stack.stack_bottom(), n, value)?;
            }
        }
        if let Some(result) = result {
            break Ok(result);
        }
    }
}
async fn do_trace ( out : & mut StandardStream , execution : & mut VmExecution , sources : & rune :: Sources , dump_stack : bool , with_source : bool , ) -> Result < Value , TraceError > { let mut current_frame_len = execution . vm ( ) . map_err ( TraceError :: VmError ) ? . call_frames ( ) . len ( ) ; loop { { let vm = execution . vm ( ) . map_err ( TraceError :: VmError ) ? ; let mut out = out . lock ( ) ; if let Some ( ( hash , signature ) ) = vm . unit ( ) . debug_info ( ) . and_then ( | d | d . function_at ( vm . ip ( ) ) ) { writeln ! ( out " " signature hash ) ? ; } let debug = vm . unit ( ) . debug_info ( ) . and_then ( | d | d . instruction_at ( vm . ip ( ) ) ) ; if with_source { let debug_info = debug . and_then ( | d | sources . get ( d . source_id ) . map ( | s | ( s , d . span ) ) ) ; if let Some ( ( source , span ) ) = debug_info { source . emit_source_line ( & mut out , span ) ? ; } } if let Some ( label ) = debug . and_then ( | d | d . label . as_ref ( ) ) { writeln ! ( out " " label ) ? ; } if let Some ( inst ) = vm . unit ( ) . instruction_at ( vm . ip ( ) ) { write ! ( out " " vm ip ( ) inst ) ? ; } else { write ! ( out " " vm ip ( ) ) ? ; } if let Some ( comment ) = debug . and_then ( | d | d . comment . as_ref ( ) ) { write ! ( out " " comment ) ? ; } writeln ! ( out ) ? ; } let result = match execution . async_step ( ) . await { Ok ( result ) => result , Err ( e ) => return Err ( TraceError :: VmError ( e ) ) , } ; let mut out = out . lock ( ) ; if dump_stack { let vm = execution . vm ( ) . map_err ( TraceError :: VmError ) ? ; let frames = vm . call_frames ( ) ; let stack = vm . stack ( ) ; if current_frame_len != frames . len ( ) { if current_frame_len < frames . len ( ) { writeln ! ( out " " frames len ( ) stack stack_bottom ( ) ) ? ; } else { writeln ! ( out " " frames len ( ) stack stack_bottom ( ) ) ? ; } current_frame_len = frames . len ( ) ; } let values = stack . get ( stack . stack_bottom ( ) .. ) . expect ( " " ) ; if values . is_empty ( ) { writeln ! ( out " " ) ? ; } for ( n , value ) in values . iter ( ) . enumerate ( ) { writeln ! ( out " " stack stack_bottom ( ) n value ) ? ; } } if let Some ( result ) = result { break Ok ( result ) ; } } }
Perform a detailed trace of the program.
Perform a detailed trace of the program .
out
&mut StandardStream
execution
&mut VmExecution
sources
&rune::Sources
dump_stack
bool
with_source
bool
out
&mut StandardStream
execution
&mut VmExecution
sources
&rune::Sources
dump_stack
bool
with_source
bool