Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/wast/src/component/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 35 kB image not shown  

Quelle  func.rs

  Sprache: Rust
 

use crate::component::*;
use crate::kw;
use crate::parser::{Cursor, Lookahead1, Parse, Parser, Peek, Result};
use crate::token::{Id, Index, LParen, NameAnnotation, Span};

/// A declared core function.
///
/// This is a member of both the core alias and canon sections.
#[derive(Debug)]
pub struct CoreFunc<'a> {
    /// Where this `core func` was defined.
    pub span: Span,
    /// An identifier that this function is resolved with (optionally) for name
    /// resolution.
    pub id: Option<Id<'a>>,
    /// An optional name for this function stored in the custom `name` section.
    pub name: Option<NameAnnotation<'a>>,
    /// The kind of core function.
    pub kind: CoreFuncKind<'a>,
}

impl<'a> Parse<'a> for CoreFunc<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let span = parser.parse::<kw::core>()?.0;
        parser.parse::<kw::func>()?;
        let id = parser.parse()?;
        let name = parser.parse()?;
        let kind = parser.parens(|p| p.parse())?;

        Ok(Self {
            span,
            id,
            name,
            kind,
        })
    }
}

/// Represents the kind of core functions.
#[derive(Debug)]
#[allow(missing_docs)]
pub enum CoreFuncKind<'a> {
    /// The core function is defined in terms of lowering a component function.
    ///
    /// The core function is actually a member of the canon section.
    Lower(CanonLower<'a>),
    /// The core function is defined in terms of aliasing a module instance export.
    ///
    /// The core function is actually a member of the core alias section.
    Alias(InlineExportAlias<'a, true>),
    ResourceNew(CanonResourceNew<'a>),
    ResourceDrop(CanonResourceDrop<'a>),
    ResourceRep(CanonResourceRep<'a>),
    ThreadSpawnRef(CanonThreadSpawnRef<'a>),
    ThreadSpawnIndirect(CanonThreadSpawnIndirect<'a>),
    ThreadAvailableParallelism(CanonThreadAvailableParallelism),
    BackpressureInc,
    BackpressureDec,
    TaskReturn(CanonTaskReturn<'a>),
    TaskCancel,
    ContextGet(u32),
    ContextSet(u32),
    ThreadYield(CanonThreadYield),
    SubtaskDrop,
    SubtaskCancel(CanonSubtaskCancel),
    StreamNew(CanonStreamNew<'a>),
    StreamRead(CanonStreamRead<'a>),
    StreamWrite(CanonStreamWrite<'a>),
    StreamCancelRead(CanonStreamCancelRead<'a>),
    StreamCancelWrite(CanonStreamCancelWrite<'a>),
    StreamDropReadable(CanonStreamDropReadable<'a>),
    StreamDropWritable(CanonStreamDropWritable<'a>),
    FutureNew(CanonFutureNew<'a>),
    FutureRead(CanonFutureRead<'a>),
    FutureWrite(CanonFutureWrite<'a>),
    FutureCancelRead(CanonFutureCancelRead<'a>),
    FutureCancelWrite(CanonFutureCancelWrite<'a>),
    FutureDropReadable(CanonFutureDropReadable<'a>),
    FutureDropWritable(CanonFutureDropWritable<'a>),
    ErrorContextNew(CanonErrorContextNew<'a>),
    ErrorContextDebugMessage(CanonErrorContextDebugMessage<'a>),
    ErrorContextDrop,
    WaitableSetNew,
    WaitableSetWait(CanonWaitableSetWait<'a>),
    WaitableSetPoll(CanonWaitableSetPoll<'a>),
    WaitableSetDrop,
    WaitableJoin,
    ThreadIndex,
    ThreadNewIndirect(CanonThreadNewIndirect<'a>),
    ThreadSwitchTo(CanonThreadSwitchTo),
    ThreadSuspend(CanonThreadSuspend),
    ThreadResumeLater,
    ThreadYieldTo(CanonThreadYieldTo),
}

impl<'a> Parse<'a> for CoreFuncKind<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let mut l = parser.lookahead1();
        if l.peek::<kw::canon>()? {
            parser.parse::<kw::canon>()?;
        } else if l.peek::<kw::alias>()? {
            return Ok(Self::Alias(parser.parse()?));
        } else {
            return Err(l.error());
        }

        CoreFuncKind::parse_lookahead(parser.lookahead1())
    }
}

impl<'a> CoreFuncKind<'a> {
    fn parse_lookahead(mut l: Lookahead1<'a>) -> Result<CoreFuncKind<'a>> {
        let parser = l.parser();
        if l.peek::<kw::lower>()? {
            Ok(CoreFuncKind::Lower(parser.parse()?))
        } else if l.peek::<kw::resource_new>()? {
            Ok(CoreFuncKind::ResourceNew(parser.parse()?))
        } else if l.peek::<kw::resource_drop>()? {
            Ok(CoreFuncKind::ResourceDrop(parser.parse()?))
        } else if l.peek::<kw::resource_rep>()? {
            Ok(CoreFuncKind::ResourceRep(parser.parse()?))
        } else if l.peek::<kw::thread_spawn_ref>()? {
            Ok(CoreFuncKind::ThreadSpawnRef(parser.parse()?))
        } else if l.peek::<kw::thread_spawn_indirect>()? {
            Ok(CoreFuncKind::ThreadSpawnIndirect(parser.parse()?))
        } else if l.peek::<kw::thread_available_parallelism>()? {
            Ok(CoreFuncKind::ThreadAvailableParallelism(parser.parse()?))
        } else if l.peek::<kw::backpressure_inc>()? {
            parser.parse::<kw::backpressure_inc>()?;
            Ok(CoreFuncKind::BackpressureInc)
        } else if l.peek::<kw::backpressure_dec>()? {
            parser.parse::<kw::backpressure_dec>()?;
            Ok(CoreFuncKind::BackpressureDec)
        } else if l.peek::<kw::task_return>()? {
            Ok(CoreFuncKind::TaskReturn(parser.parse()?))
        } else if l.peek::<kw::task_cancel>()? {
            parser.parse::<kw::task_cancel>()?;
            Ok(CoreFuncKind::TaskCancel)
        } else if l.peek::<kw::context_get>()? {
            parser.parse::<kw::context_get>()?;
            parser.parse::<kw::i32>()?;
            Ok(CoreFuncKind::ContextGet(parser.parse()?))
        } else if l.peek::<kw::context_set>()? {
            parser.parse::<kw::context_set>()?;
            parser.parse::<kw::i32>()?;
            Ok(CoreFuncKind::ContextSet(parser.parse()?))
        } else if l.peek::<kw::thread_yield>()? {
            Ok(CoreFuncKind::ThreadYield(parser.parse()?))
        } else if l.peek::<kw::subtask_drop>()? {
            parser.parse::<kw::subtask_drop>()?;
            Ok(CoreFuncKind::SubtaskDrop)
        } else if l.peek::<kw::subtask_cancel>()? {
            Ok(CoreFuncKind::SubtaskCancel(parser.parse()?))
        } else if l.peek::<kw::stream_new>()? {
            Ok(CoreFuncKind::StreamNew(parser.parse()?))
        } else if l.peek::<kw::stream_read>()? {
            Ok(CoreFuncKind::StreamRead(parser.parse()?))
        } else if l.peek::<kw::stream_write>()? {
            Ok(CoreFuncKind::StreamWrite(parser.parse()?))
        } else if l.peek::<kw::stream_cancel_read>()? {
            Ok(CoreFuncKind::StreamCancelRead(parser.parse()?))
        } else if l.peek::<kw::stream_cancel_write>()? {
            Ok(CoreFuncKind::StreamCancelWrite(parser.parse()?))
        } else if l.peek::<kw::stream_drop_readable>()? {
            Ok(CoreFuncKind::StreamDropReadable(parser.parse()?))
        } else if l.peek::<kw::stream_drop_writable>()? {
            Ok(CoreFuncKind::StreamDropWritable(parser.parse()?))
        } else if l.peek::<kw::future_new>()? {
            Ok(CoreFuncKind::FutureNew(parser.parse()?))
        } else if l.peek::<kw::future_read>()? {
            Ok(CoreFuncKind::FutureRead(parser.parse()?))
        } else if l.peek::<kw::future_write>()? {
            Ok(CoreFuncKind::FutureWrite(parser.parse()?))
        } else if l.peek::<kw::future_cancel_read>()? {
            Ok(CoreFuncKind::FutureCancelRead(parser.parse()?))
        } else if l.peek::<kw::future_cancel_write>()? {
            Ok(CoreFuncKind::FutureCancelWrite(parser.parse()?))
        } else if l.peek::<kw::future_drop_readable>()? {
            Ok(CoreFuncKind::FutureDropReadable(parser.parse()?))
        } else if l.peek::<kw::future_drop_writable>()? {
            Ok(CoreFuncKind::FutureDropWritable(parser.parse()?))
        } else if l.peek::<kw::error_context_new>()? {
            Ok(CoreFuncKind::ErrorContextNew(parser.parse()?))
        } else if l.peek::<kw::error_context_debug_message>()? {
            Ok(CoreFuncKind::ErrorContextDebugMessage(parser.parse()?))
        } else if l.peek::<kw::error_context_drop>()? {
            parser.parse::<kw::error_context_drop>()?;
            Ok(CoreFuncKind::ErrorContextDrop)
        } else if l.peek::<kw::waitable_set_new>()? {
            parser.parse::<kw::waitable_set_new>()?;
            Ok(CoreFuncKind::WaitableSetNew)
        } else if l.peek::<kw::waitable_set_wait>()? {
            Ok(CoreFuncKind::WaitableSetWait(parser.parse()?))
        } else if l.peek::<kw::waitable_set_poll>()? {
            Ok(CoreFuncKind::WaitableSetPoll(parser.parse()?))
        } else if l.peek::<kw::waitable_set_drop>()? {
            parser.parse::<kw::waitable_set_drop>()?;
            Ok(CoreFuncKind::WaitableSetDrop)
        } else if l.peek::<kw::waitable_join>()? {
            parser.parse::<kw::waitable_join>()?;
            Ok(CoreFuncKind::WaitableJoin)
        } else if l.peek::<kw::thread_index>()? {
            parser.parse::<kw::thread_index>()?;
            Ok(CoreFuncKind::ThreadIndex)
        } else if l.peek::<kw::thread_new_indirect>()? {
            Ok(CoreFuncKind::ThreadNewIndirect(parser.parse()?))
        } else if l.peek::<kw::thread_switch_to>()? {
            Ok(CoreFuncKind::ThreadSwitchTo(parser.parse()?))
        } else if l.peek::<kw::thread_suspend>()? {
            Ok(CoreFuncKind::ThreadSuspend(parser.parse()?))
        } else if l.peek::<kw::thread_resume_later>()? {
            parser.parse::<kw::thread_resume_later>()?;
            Ok(CoreFuncKind::ThreadResumeLater)
        } else if l.peek::<kw::thread_yield_to>()? {
            Ok(CoreFuncKind::ThreadYieldTo(parser.parse()?))
        } else {
            Err(l.error())
        }
    }
}

/// A declared component function.
///
/// This may be a member of the import, alias, or canon sections.
#[derive(Debug)]
pub struct Func<'a> {
    /// Where this `func` was defined.
    pub span: Span,
    /// An identifier that this function is resolved with (optionally) for name
    /// resolution.
    pub id: Option<Id<'a>>,
    /// An optional name for this function stored in the custom `name` section.
    pub name: Option<NameAnnotation<'a>>,
    /// If present, inline export annotations which indicate names this
    /// definition should be exported under.
    pub exports: InlineExport<'a>,
    /// The kind of function.
    pub kind: FuncKind<'a>,
}

impl<'a> Parse<'a> for Func<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let span = parser.parse::<kw::func>()?.0;
        let id = parser.parse()?;
        let name = parser.parse()?;
        let exports = parser.parse()?;
        let kind = parser.parse()?;

        Ok(Self {
            span,
            id,
            name,
            exports,
            kind,
        })
    }
}

/// Represents the kind of component functions.
#[derive(Debug)]
pub enum FuncKind<'a> {
    /// A function which is actually defined as an import, such as:
    ///
    /// ```text
    /// (func (import "foo") (param string))
    /// ```
    Import {
        /// The import name of this import.
        import: InlineImport<'a>,
        /// The type that this function will have.
        ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>,
    },
    /// The function is defined in terms of lifting a core function.
    ///
    /// The function is actually a member of the canon section.
    Lift {
        /// The lifted function's type.
        ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>,
        /// Information relating to the lifting of the core function.
        info: CanonLift<'a>,
    },
    /// The function is defined in terms of aliasing a component instance export.
    ///
    /// The function is actually a member of the alias section.
    Alias(InlineExportAlias<'a, false>),
}

impl<'a> Parse<'a> for FuncKind<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        if let Some(import) = parser.parse()? {
            Ok(Self::Import {
                import,
                ty: parser.parse()?,
            })
        } else if parser.peek::<LParen>()? && parser.peek2::<kw::alias>()? {
            parser.parens(|parser| Ok(Self::Alias(parser.parse()?)))
        } else {
            Ok(Self::Lift {
                ty: parser.parse()?,
                info: parser.parens(|parser| {
                    parser.parse::<kw::canon>()?;
                    parser.parse()
                })?,
            })
        }
    }
}

/// A WebAssembly canonical function to be inserted into a component.
///
/// This is a member of the canonical section.
#[derive(Debug)]
pub struct CanonicalFunc<'a> {
    /// Where this `func` was defined.
    pub span: Span,
    /// An identifier that this function is resolved with (optionally) for name
    /// resolution.
    pub id: Option<Id<'a>>,
    /// An optional name for this function stored in the custom `name` section.
    pub name: Option<NameAnnotation<'a>>,
    /// What kind of function this is, be it a lowered or lifted function.
    pub kind: CanonicalFuncKind<'a>,
}

impl<'a> Parse<'a> for CanonicalFunc<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let span = parser.parse::<kw::canon>()?.0;
        let mut l = parser.lookahead1();

        if l.peek::<kw::lift>()? {
            let info = parser.parse()?;
            let (id, name, ty) = parser.parens(|parser| {
                parser.parse::<kw::func>()?;
                let id = parser.parse()?;
                let name = parser.parse()?;
                let ty = parser.parse()?;
                Ok((id, name, ty))
            })?;

            Ok(Self {
                span,
                id,
                name,
                kind: CanonicalFuncKind::Lift { info, ty },
            })
        } else {
            let kind = CoreFuncKind::parse_lookahead(l)?;
            let (id, name) = parser.parens(|parser| {
                parser.parse::<kw::core>()?;
                parser.parse::<kw::func>()?;
                let id = parser.parse()?;
                let name = parser.parse()?;
                Ok((id, name))
            })?;

            Ok(Self {
                span,
                id,
                name,
                kind: CanonicalFuncKind::Core(kind),
            })
        }
    }
}

/// Possible ways to define a canonical function in the text format.
#[derive(Debug)]
#[allow(missing_docs)]
pub enum CanonicalFuncKind<'a> {
    /// A canonical function that is defined in terms of lifting a core function.
    Lift {
        /// The lifted function's type.
        ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>,
        /// Information relating to the lifting of the core function.
        info: CanonLift<'a>,
    },

    /// A canonical function that defines a core function, whose variants are
    /// delegated to `CoreFuncKind`.
    Core(CoreFuncKind<'a>),
}

/// Information relating to lifting a core function.
#[derive(Debug)]
pub struct CanonLift<'a> {
    /// The core function being lifted.
    pub func: CoreItemRef<'a, kw::func>,
    /// The canonical options for the lifting.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonLift<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::lift>()?;

        Ok(Self {
            func: parser.parens(|parser| {
                parser.parse::<kw::core>()?;
                parser.parse()
            })?,
            opts: parser.parse()?,
        })
    }
}

impl Default for CanonLift<'_> {
    fn default() -> Self {
        let span = Span::from_offset(0);
        Self {
            func: CoreItemRef {
                kind: kw::func(span),
                idx: Index::Num(0, span),
                export_name: None,
            },
            opts: Vec::new(),
        }
    }
}

/// Information relating to lowering a component function.
#[derive(Debug)]
pub struct CanonLower<'a> {
    /// The function being lowered.
    pub func: ItemRef<'a, kw::func>,
    /// The canonical options for the lowering.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonLower<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::lower>()?;

        Ok(Self {
            func: parser.parens(|parser| parser.parse())?,
            opts: parser.parse()?,
        })
    }
}

impl Default for CanonLower<'_> {
    fn default() -> Self {
        let span = Span::from_offset(0);
        Self {
            func: ItemRef {
                kind: kw::func(span),
                idx: Index::Num(0, span),
                export_names: Vec::new(),
            },
            opts: Vec::new(),
        }
    }
}

/// Information relating to the `resource.new` intrinsic.
#[derive(Debug)]
pub struct CanonResourceNew<'a> {
    /// The resource type that this intrinsic creates an owned reference to.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonResourceNew<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::resource_new>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `resource.drop` intrinsic.
#[derive(Debug)]
pub struct CanonResourceDrop<'a> {
    /// The resource type that this intrinsic is dropping.
    pub ty: Index<'a>,
    /// Whether or not this function is async
    pub async_: bool,
}

impl<'a> Parse<'a> for CanonResourceDrop<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::resource_drop>()?;

        Ok(Self {
            ty: parser.parse()?,
            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
        })
    }
}

/// Information relating to the `resource.rep` intrinsic.
#[derive(Debug)]
pub struct CanonResourceRep<'a> {
    /// The resource type that this intrinsic is accessing.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonResourceRep<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::resource_rep>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `thread.spawn-ref` intrinsic.
#[derive(Debug)]
pub struct CanonThreadSpawnRef<'a> {
    /// The function type that is being spawned.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonThreadSpawnRef<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_spawn_ref>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `thread.spawn-indirect` intrinsic.
///
/// This should look quite similar to parsing of `CallIndirect`.
#[derive(Debug)]
pub struct CanonThreadSpawnIndirect<'a> {
    /// The function type that is being spawned.
    pub ty: Index<'a>,
    /// The table that this spawn is going to be indexing.
    pub table: CoreItemRef<'a, kw::table>,
}

impl<'a> Parse<'a> for CanonThreadSpawnIndirect<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_spawn_indirect>()?;
        let ty = parser.parse()?;
        let table = parser.parens(|p| p.parse())?;
        Ok(Self { ty, table })
    }
}

/// Information relating to the `thread.spawn` intrinsic.
#[derive(Debug)]
pub struct CanonThreadAvailableParallelism;

impl<'a> Parse<'a> for CanonThreadAvailableParallelism {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_available_parallelism>()?;
        Ok(Self)
    }
}

/// Information relating to the `task.return` intrinsic.
#[derive(Debug)]
pub struct CanonTaskReturn<'a> {
    /// The type of the result which may be returned with this intrinsic.
    pub result: Option<ComponentValType<'a>>,
    /// The canonical options for storing values.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonTaskReturn<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::task_return>()?;

        Ok(Self {
            result: if parser.peek2::<kw::result>()? {
                Some(parser.parens(|p| {
                    p.parse::<kw::result>()?.0;
                    p.parse()
                })?)
            } else {
                None
            },
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `waitable-set.wait` intrinsic.
#[derive(Debug)]
pub struct CanonWaitableSetWait<'a> {
    /// If true, the component instance may be reentered during a call to this
    /// intrinsic.
    pub async_: bool,
    /// The memory to use when returning an event to the caller.
    pub memory: CoreItemRef<'a, kw::memory>,
}

impl<'a> Parse<'a> for CanonWaitableSetWait<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::waitable_set_wait>()?;
        let async_ = parser.parse::<Option<kw::cancellable>>()?.is_some();
        let memory = parser.parens(|p| p.parse())?;

        Ok(Self { async_, memory })
    }
}

/// Information relating to the `waitable-set.poll` intrinsic.
#[derive(Debug)]
pub struct CanonWaitableSetPoll<'a> {
    /// If true, the component instance may be reentered during a call to this
    /// intrinsic.
    pub async_: bool,
    /// The memory to use when returning an event to the caller.
    pub memory: CoreItemRef<'a, kw::memory>,
}

impl<'a> Parse<'a> for CanonWaitableSetPoll<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::waitable_set_poll>()?;
        let async_ = parser.parse::<Option<kw::cancellable>>()?.is_some();
        let memory = parser.parens(|p| p.parse())?;

        Ok(Self { async_, memory })
    }
}

/// Information relating to the `thread.yield` intrinsic.
#[derive(Debug)]
pub struct CanonThreadYield {
    /// If true, the component instance may be reentered during a call to this
    /// intrinsic.
    pub cancellable: bool,
}

impl<'a> Parse<'a> for CanonThreadYield {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_yield>()?;
        let cancellable = parser.parse::<Option<kw::cancellable>>()?.is_some();

        Ok(Self { cancellable })
    }
}

/// Information relating to the `subtask.cancel` intrinsic.
#[derive(Debug)]
pub struct CanonSubtaskCancel {
    /// If false, block until cancel is finished; otherwise return BLOCKED if
    /// necessary.
    pub async_: bool,
}

impl<'a> Parse<'a> for CanonSubtaskCancel {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::subtask_cancel>()?;
        let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();

        Ok(Self { async_ })
    }
}

/// Information relating to the `stream.new` intrinsic.
#[derive(Debug)]
pub struct CanonStreamNew<'a> {
    /// The stream type to instantiate.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonStreamNew<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_new>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `stream.read` intrinsic.
#[derive(Debug)]
pub struct CanonStreamRead<'a> {
    /// The stream type to instantiate.
    pub ty: Index<'a>,
    /// The canonical options for storing values.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonStreamRead<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_read>()?;

        Ok(Self {
            ty: parser.parse()?,
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `stream.write` intrinsic.
#[derive(Debug)]
pub struct CanonStreamWrite<'a> {
    /// The stream type to instantiate.
    pub ty: Index<'a>,
    /// The canonical options for loading values.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonStreamWrite<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_write>()?;

        Ok(Self {
            ty: parser.parse()?,
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `stream.cancel-read` intrinsic.
#[derive(Debug)]
pub struct CanonStreamCancelRead<'a> {
    /// The stream type to instantiate.
    pub ty: Index<'a>,
    /// If false, block until cancel is finished; otherwise return BLOCKED if
    /// necessary.
    pub async_: bool,
}

impl<'a> Parse<'a> for CanonStreamCancelRead<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_cancel_read>()?;

        Ok(Self {
            ty: parser.parse()?,
            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
        })
    }
}

/// Information relating to the `stream.cancel-write` intrinsic.
#[derive(Debug)]
pub struct CanonStreamCancelWrite<'a> {
    /// The stream type to instantiate.
    pub ty: Index<'a>,
    /// If false, block until cancel is finished; otherwise return BLOCKED if
    /// necessary.
    pub async_: bool,
}

impl<'a> Parse<'a> for CanonStreamCancelWrite<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_cancel_write>()?;

        Ok(Self {
            ty: parser.parse()?,
            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
        })
    }
}

/// Information relating to the `stream.drop-readable` intrinsic.
#[derive(Debug)]
pub struct CanonStreamDropReadable<'a> {
    /// The stream type to drop.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonStreamDropReadable<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_drop_readable>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `stream.drop-writable` intrinsic.
#[derive(Debug)]
pub struct CanonStreamDropWritable<'a> {
    /// The stream type to drop.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonStreamDropWritable<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::stream_drop_writable>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `future.new` intrinsic.
#[derive(Debug)]
pub struct CanonFutureNew<'a> {
    /// The future type to instantiate.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonFutureNew<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_new>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `future.read` intrinsic.
#[derive(Debug)]
pub struct CanonFutureRead<'a> {
    /// The future type to instantiate.
    pub ty: Index<'a>,
    /// The canonical options for storing values.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonFutureRead<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_read>()?;

        Ok(Self {
            ty: parser.parse()?,
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `future.write` intrinsic.
#[derive(Debug)]
pub struct CanonFutureWrite<'a> {
    /// The future type to instantiate.
    pub ty: Index<'a>,
    /// The canonical options for loading values.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonFutureWrite<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_write>()?;

        Ok(Self {
            ty: parser.parse()?,
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `future.cancel-read` intrinsic.
#[derive(Debug)]
pub struct CanonFutureCancelRead<'a> {
    /// The future type to instantiate.
    pub ty: Index<'a>,
    /// If false, block until cancel is finished; otherwise return BLOCKED if
    /// necessary.
    pub async_: bool,
}

impl<'a> Parse<'a> for CanonFutureCancelRead<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_cancel_read>()?;

        Ok(Self {
            ty: parser.parse()?,
            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
        })
    }
}

/// Information relating to the `future.cancel-write` intrinsic.
#[derive(Debug)]
pub struct CanonFutureCancelWrite<'a> {
    /// The future type to instantiate.
    pub ty: Index<'a>,
    /// If false, block until cancel is finished; otherwise return BLOCKED if
    /// necessary.
    pub async_: bool,
}

impl<'a> Parse<'a> for CanonFutureCancelWrite<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_cancel_write>()?;

        Ok(Self {
            ty: parser.parse()?,
            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
        })
    }
}

/// Information relating to the `future.drop-readable` intrinsic.
#[derive(Debug)]
pub struct CanonFutureDropReadable<'a> {
    /// The future type to drop.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonFutureDropReadable<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_drop_readable>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `future.drop-writable` intrinsic.
#[derive(Debug)]
pub struct CanonFutureDropWritable<'a> {
    /// The future type to drop.
    pub ty: Index<'a>,
}

impl<'a> Parse<'a> for CanonFutureDropWritable<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::future_drop_writable>()?;

        Ok(Self {
            ty: parser.parse()?,
        })
    }
}

/// Information relating to the `error-context.new` intrinsic.
#[derive(Debug)]
pub struct CanonErrorContextNew<'a> {
    /// The canonical options for loading the debug message.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonErrorContextNew<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::error_context_new>()?;

        Ok(Self {
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `error-context.debug-message` intrinsic.
#[derive(Debug)]
pub struct CanonErrorContextDebugMessage<'a> {
    /// The canonical options for storing the debug message.
    pub opts: Vec<CanonOpt<'a>>,
}

impl<'a> Parse<'a> for CanonErrorContextDebugMessage<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::error_context_debug_message>()?;

        Ok(Self {
            opts: parser.parse()?,
        })
    }
}

/// Information relating to the `thread.new-indirect` intrinsic.
#[derive(Debug)]
pub struct CanonThreadNewIndirect<'a> {
    /// The function type for the thread start function.
    pub ty: Index<'a>,
    /// The table to index.
    pub table: CoreItemRef<'a, kw::table>,
}

impl<'a> Parse<'a> for CanonThreadNewIndirect<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_new_indirect>()?;
        let ty = parser.parse()?;
        let table = parser.parens(|p| p.parse())?;
        Ok(Self { ty, table })
    }
}

/// Information relating to the `thread.switch-to` intrinsic.
#[derive(Debug)]
pub struct CanonThreadSwitchTo {
    /// Whether the thread can be cancelled while suspended at this point.
    pub cancellable: bool,
}

impl<'a> Parse<'a> for CanonThreadSwitchTo {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_switch_to>()?;
        let cancellable = parser.parse::<Option<kw::cancellable>>()?.is_some();
        Ok(Self { cancellable })
    }
}

/// Information relating to the `thread.suspend` intrinsic.
#[derive(Debug)]
pub struct CanonThreadSuspend {
    /// Whether the thread can be cancelled while suspended at this point.
    pub cancellable: bool,
}
impl<'a> Parse<'a> for CanonThreadSuspend {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_suspend>()?;
        let cancellable = parser.parse::<Option<kw::cancellable>>()?.is_some();
        Ok(Self { cancellable })
    }
}

/// Information relating to the `thread.yield-to` intrinsic.
#[derive(Debug)]
pub struct CanonThreadYieldTo {
    /// Whether the thread can be cancelled while yielding at this point.
    pub cancellable: bool,
}
impl<'a> Parse<'a> for CanonThreadYieldTo {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        parser.parse::<kw::thread_yield_to>()?;
        let cancellable = parser.parse::<Option<kw::cancellable>>()?.is_some();
        Ok(Self { cancellable })
    }
}

#[derive(Debug)]
/// Canonical ABI options.
pub enum CanonOpt<'a> {
    /// Encode strings as UTF-8.
    StringUtf8,
    /// Encode strings as UTF-16.
    StringUtf16,
    /// Encode strings as "compact UTF-16".
    StringLatin1Utf16,
    /// Use the specified memory for canonical ABI memory access.
    Memory(CoreItemRef<'a, kw::memory>),
    /// Use the specified reallocation function for memory allocations.
    Realloc(CoreItemRef<'a, kw::func>),
    /// Call the specified function after the lifted function has returned.
    PostReturn(CoreItemRef<'a, kw::func>),
    /// Use the async ABI for lifting or lowering.
    Async,
    /// Use the specified function to deliver async events to stackless coroutines.
    Callback(CoreItemRef<'a, kw::func>),
    /// Lower this component function into the specified core function type.
    CoreType(CoreItemRef<'a, kw::r#type>),
    /// Use the GC variant of the canonical ABI.
    Gc,
}

impl Default for kw::r#type {
    fn default() -> Self {
        Self(Span::from_offset(0))
    }
}

impl<'a> Parse<'a> for CanonOpt<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let mut l = parser.lookahead1();
        if l.peek::<kw::string_utf8>()? {
            parser.parse::<kw::string_utf8>()?;
            Ok(Self::StringUtf8)
        } else if l.peek::<kw::string_utf16>()? {
            parser.parse::<kw::string_utf16>()?;
            Ok(Self::StringUtf16)
        } else if l.peek::<kw::string_latin1_utf16>()? {
            parser.parse::<kw::string_latin1_utf16>()?;
            Ok(Self::StringLatin1Utf16)
        } else if l.peek::<kw::r#async>()? {
            parser.parse::<kw::r#async>()?;
            Ok(Self::Async)
        } else if l.peek::<kw::gc>()? {
            parser.parse::<kw::gc>()?;
            Ok(Self::Gc)
        } else if l.peek::<LParen>()? {
            parser.parens(|parser| {
                let mut l = parser.lookahead1();
                if l.peek::<kw::memory>()? {
                    Ok(CanonOpt::Memory(parser.parse()?))
                } else if l.peek::<kw::realloc>()? {
                    parser.parse::<kw::realloc>()?;
                    Ok(CanonOpt::Realloc(
                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
                    ))
                } else if l.peek::<kw::post_return>()? {
                    parser.parse::<kw::post_return>()?;
                    Ok(CanonOpt::PostReturn(
                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
                    ))
                } else if l.peek::<kw::callback>()? {
                    parser.parse::<kw::callback>()?;
                    Ok(CanonOpt::Callback(
                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
                    ))
                } else if l.peek::<kw::core_type>()? {
                    parser.parse::<kw::core_type>()?;
                    Ok(CanonOpt::CoreType(
                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
                    ))
                } else {
                    Err(l.error())
                }
            })
        } else {
            Err(l.error())
        }
    }
}

impl Peek for CanonOpt<'_> {
    fn peek(cursor: Cursor<'_>) -> Result<bool> {
        Ok(kw::string_utf8::peek(cursor)?
            || kw::string_utf16::peek(cursor)?
            || kw::string_latin1_utf16::peek(cursor)?
            || kw::r#async::peek(cursor)?
            || kw::gc::peek(cursor)?
            || match cursor.lparen()? {
                Some(next) => {
                    kw::memory::peek(next)?
                        || kw::realloc::peek(next)?
                        || kw::post_return::peek(next)?
                        || kw::callback::peek(next)?
                        || kw::core_type::peek(next)?
                }
                None => false,
            })
    }

    fn display() -> &'static str {
        "canonical option"
    }
}

impl<'a> Parse<'a> for Vec<CanonOpt<'a>> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let mut funcs = Vec::new();
        while parser.peek::<CanonOpt<'_>>()? {
            funcs.push(parser.parse()?);
        }
        Ok(funcs)
    }
}

Messung V0.5 in Prozent
C=91 H=90 G=90

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.