extism/js-sdk

Deno fail to run plugin

Closed this issue · 7 comments

setup rust pdk + deno sdk

rust (crate name = "plugin")

use extism_pdk::*;

#[plugin_fn]
pub fn greet(name: String) -> FnResult<String> {
    unsafe { world().unwrap() };
    Ok(format!("Hello {name}!"))
}

#[host_fn]
extern "ExtismHost" {
    fn world() -> String;
}

deno

#!/usr/bin/env deno run -A
import createPlugin from "https://raw.githubusercontent.com/extism/js-sdk/v1.0.0-rc9/src/mod.ts";

const cargoTargetDir = Deno.env.get("CARGO_TARGET_DIR") || "target";
const filename = Deno.args[0] ||
  `${cargoTargetDir}/wasm32-unknown-unknown/debug/plugin.wasm`;
const funcname = Deno.args[1] || "greet";
const input = Deno.args[2] || "myname";

const plugin = await createPlugin(filename, {
  functions: {
    "extism:host/user": { world: () => console.log("world") },
  },
});

const res = await plugin.call(funcname, new TextEncoder().encode(input));
if (!res) throw new Error("plugin call failed");
const s = new TextDecoder().decode(res.buffer);
console.log(s);

await plugin.close();

run with

cargo b --target wasm32-unknown-unknown && deno run --import-map https://raw.githubusercontent.com/extism/js-sdk/main/deno.json -A deno_run.ts

it outputs world correctly then fails with

TypeError: Cannot convert undefined to a BigInt
    at _ZN6plugin5world17h08a1d83f43a6779fE (wasm://wasm/013b541e:1:6969)
    at _ZN6plugin5greet5inner17h28caeb1ca07e97f5E (wasm://wasm/013b541e:1:6607)
    at greet (wasm://wasm/013b541e:1:4599)
    at ForegroundPlugin.callBlock (https://raw.githubusercontent.com/extism/js-sdk/main/src/foreground-plugin.ts:93:7)
    at https://raw.githubusercontent.com/extism/js-sdk/main/src/worker.ts:41:49
    at Reactor.handleInvoke (https://raw.githubusercontent.com/extism/js-sdk/main/src/worker.ts:100:27)
    at Reactor.handleMessage (https://raw.githubusercontent.com/extism/js-sdk/main/src/worker.ts:86:27)
    at https://raw.githubusercontent.com/extism/js-sdk/main/src/worker.ts:28:47
    at _listener (node:worker_threads:158:33)
    at innerInvokeEventListeners (ext:deno_web/02_event.js:753:7)

if I remove the using of the host function in rust it works

Hey @sigmaSd, thanks for the report!

out of curiosity, does the plug-in call work fully if you skip the TextEncoder parts and instead, pass input directly and log res.text()?

the error seems more related to how the plug-in output is being used in Deno vs. something wrong with the plug-in itself. checking this will help support that theory!

This seems to be an issue with the host function types. In the plugin the type of the hello function is () -> String but the actual host function implementation doesn't return any value. The plugin is expecting a host function that returns an I64 Extism pointer, which on the JS side is represented by a BigInt.

Oh good eye, @zshipko!

Ignore my recommendation.. I haven't had enough coffee yet 😳

You need to either change the HostFn declaration in Rust to return nothing, or return a placeholder BigInt from the TS import object definition. I think 0 could work as long as you don't use it in your plugin anyways.

oh my bad, I didn't see it, though changing to

    "extism:host/user": {
      world: () => {
        return "world";
      },
    },

still shows the same error

Instead of "world", return 0, or BigInt(0) (or however you type a number as a big int in TS).

this value is a pointer to memory

@sigmaSd can you try this?

    "extism:host/user": {
      world: (cp: CurrentPlugin) => {
        return cp.store("world");
      },
    },

CurrentPlugin.store stores the string world into the wasm memory and returns the offset

Thanks that works