diff options
| author | Laurenz <laurmaedje@gmail.com> | 2025-06-19 17:45:00 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2025-06-20 17:32:37 +0200 |
| commit | 3602d06a155a0567fe2b2e75a4d5970578d0f14f (patch) | |
| tree | 0e609071791c7ab92f4774acc6e3c775c23482ec /crates/typst-library | |
| parent | 15302dbe7a6bd04125c4a56fee24bbbacfb4cc2f (diff) | |
Support for generating native functions at runtime
Diffstat (limited to 'crates/typst-library')
| -rw-r--r-- | crates/typst-library/src/foundations/func.rs | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/crates/typst-library/src/foundations/func.rs b/crates/typst-library/src/foundations/func.rs index 27eb34ea..9ef81289 100644 --- a/crates/typst-library/src/foundations/func.rs +++ b/crates/typst-library/src/foundations/func.rs @@ -307,7 +307,7 @@ impl Func { ) -> SourceResult<Value> { match &self.repr { Repr::Native(native) => { - let value = (native.function)(engine, context, &mut args)?; + let value = (native.function.0)(engine, context, &mut args)?; args.finish()?; Ok(value) } @@ -491,8 +491,8 @@ pub trait NativeFunc { /// Defines a native function. #[derive(Debug)] pub struct NativeFuncData { - /// Invokes the function from Typst. - pub function: fn(&mut Engine, Tracked<Context>, &mut Args) -> SourceResult<Value>, + /// The implementation of the function. + pub function: NativeFuncPtr, /// The function's normal name (e.g. `align`), as exposed to Typst. pub name: &'static str, /// The function's title case name (e.g. `Align`). @@ -504,11 +504,11 @@ pub struct NativeFuncData { /// Whether this function makes use of context. pub contextual: bool, /// Definitions in the scope of the function. - pub scope: LazyLock<Scope>, + pub scope: DynLazyLock<Scope>, /// A list of parameter information for each parameter. - pub params: LazyLock<Vec<ParamInfo>>, + pub params: DynLazyLock<Vec<ParamInfo>>, /// Information about the return value of this function. - pub returns: LazyLock<CastInfo>, + pub returns: DynLazyLock<CastInfo>, } cast! { @@ -516,6 +516,28 @@ cast! { self => Func::from(self).into_value(), } +/// A pointer to a native function's implementation. +pub struct NativeFuncPtr(pub &'static NativeFuncSignature); + +/// The signature of a native function's implementation. +type NativeFuncSignature = + dyn Fn(&mut Engine, Tracked<Context>, &mut Args) -> SourceResult<Value> + Send + Sync; + +impl Debug for NativeFuncPtr { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.pad("NativeFuncPtr(..)") + } +} + +/// A `LazyLock` that uses a static closure for initialization instead of only +/// working with function pointers. +/// +/// Can be created from a normal function or closure by prepending with a `&`, +/// e.g. `LazyLock::new(&|| "hello")`. Can be created from a dynamic closure +/// by allocating and then leaking it. This is equivalent to having it +/// statically allocated, but allows for it to be generated at runtime. +type DynLazyLock<T> = LazyLock<T, &'static (dyn Fn() -> T + Send + Sync)>; + /// Describes a function parameter. #[derive(Debug, Clone)] pub struct ParamInfo { |
