Compare commits

...

71 Commits

Author SHA1 Message Date
Benjamin Eckel
f4c61e8c44 feat: add default cache config (#615)
Co-authored-by: zach <zach@dylibso.com>
2023-11-29 14:32:01 -06:00
Benjamin Eckel
452bb2f498 chore: Bump 0.5.4 (#549) 2023-10-25 15:46:30 -05:00
zach
c043decd95 chore: backport latest kernel changes (#547)
- Updates to fix a possible issue with a value on stack being stored at
a very high offset in extism kernel memory
2023-10-25 11:37:37 -07:00
Benjamin Eckel
ec70b0e7b8 Release: 0.5.3 stable release (#538)
Cuts a new 0.5.3 release from stable.
2023-10-24 12:29:39 -05:00
zach
1452b9fb42 chore: backport latest kernel changes to stable (#528) 2023-10-20 10:16:33 -07:00
Benjamin Eckel
9f69a68df4 chore: fix elixir release action (#497)
This is 404ing for some reason. But Elixir doesn't need the shared
library so i'm removing it.

https://github.com/extism/extism/actions/runs/6425026823/job/17446865267
2023-10-05 17:32:20 -05:00
Benjamin Eckel
dbf9f34dc6 chore: Release elixir v0.5.1 (#496) 2023-10-05 17:14:54 -05:00
Benjamin Eckel
c8a9478da1 chore: also bump rust SDK to 0.5.2 2023-09-21 10:22:39 -05:00
Benjamin Eckel
e89ddd5a2a chore: Bump to 0.5.2 2023-09-21 09:41:27 -05:00
zach
93392e0884 fix(stable): improve the way the kernel calculates how many pages to allocate (#471)
Fixes a bug in the kernel memory allocator where the space used by the
`MemoryRoot` wasn't being considered

---------

Co-authored-by: Benjamin Eckel <bhelx@users.noreply.github.com>
2023-09-20 16:02:42 -07:00
Benjamin Eckel
4ebd0eb372 chore: always run the publish of SDK 2023-09-18 19:17:47 -05:00
zach
8feee0c693 cleanup(stable): use wasm-strip on extism-runtime.wasm (#467) 2023-09-18 19:08:27 -05:00
Benjamin Eckel
773ab32a45 chore: Bump to 0.5.1 2023-09-18 18:55:46 -05:00
Benjamin Eckel
6a041d0c39 fix: Fixes rounding issue in kernel num_pages (#466)
There were some scenarios where the kernel was not allocating enough
pages to get data back into the plugin. So some host functions were
failing when the output was right on this boundary.

Related https://github.com/moonrepo/proto/issues/208

We will come back with tests and cherry pick this over to main. For now
we want to get out a 0.5.1 fix
2023-09-18 18:53:30 -05:00
Benjamin Eckel
745a03ece4 release: Bump elixir nif to rust 0.5 (#431) 2023-08-24 13:37:48 -05:00
Benjamin Eckel
67eb8c1571 release: Bump the rest of the SDKs (#430) 2023-08-24 12:41:31 -05:00
zach
6a15884963 fix: remove call to bash from build.rs (#429)
I think this will fix the issue with CI hanging - this fixes the issue
when building Elixir, which seems to be the same as the CI issue
2023-08-23 19:12:51 -05:00
zach
72f62c4035 chore: bump libextism version (#428) 2023-08-23 15:49:50 -05:00
Benjamin Eckel
e86398a612 release: Bump runtime to 0.5.0 (#427)
Co-authored-by: zach <zach@dylibso.com>
2023-08-23 13:58:33 -05:00
dependabot[bot]
461ac97529 chore(deps-dev): Bump prettier from 3.0.1 to 3.0.2 in /node (#422)
Bumps [prettier](https://github.com/prettier/prettier) from 3.0.1 to
3.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>3.0.2</h2>
<p>🔗 <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md#302">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>3.0.2</h1>
<p><a
href="https://github.com/prettier/prettier/compare/3.0.1...3.0.2">diff</a></p>
<h4>Break after <code>=</code> of assignment if RHS is poorly breakable
AwaitExpression or YieldExpression (<a
href="https://redirect.github.com/prettier/prettier/pull/15204">#15204</a>
by <a href="https://github.com/seiyab"><code>@​seiyab</code></a>)</h4>
<!-- raw HTML omitted -->
<pre lang="js"><code>// Input
const { section, rubric, authors, tags } = await
utils.upsertCommonData(mainData);
<p>// Prettier 3.0.1
const { section, rubric, authors, tags } = await utils.upsertCommonData(
mainData,
);</p>
<p>// Prettier 3.0.2
const { section, rubric, authors, tags } =
await utils.upsertCommonData(mainData);
</code></pre></p>
<h4>Do not add trailing comma for grouped scss comments (<a
href="https://redirect.github.com/prettier/prettier/pull/15217">#15217</a>
by <a href="https://github.com/auvred"><code>@​auvred</code></a>)</h4>
<!-- raw HTML omitted -->
<pre lang="scss"><code>/* Input */
$foo: (
	'property': (),
	// comment 1
	// comment 2
)
<p>/* Prettier 3.0.1 */
$foo: (
&quot;property&quot;: (),
// comment 1
// comment 2,
);</p>
<p>/* Prettier 3.0.2 */
$foo: (
&quot;property&quot;: (),
// comment 1
// comment 2
);
</code></pre></p>
<h4>Print <code>declare</code> and <code>export</code> keywords for
nested namespace (<a
href="https://redirect.github.com/prettier/prettier/pull/15249">#15249</a>
by <a
href="https://github.com/sosukesuzuki"><code>@​sosukesuzuki</code></a>)</h4>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="157e42accd"><code>157e42a</code></a>
Release 3.0.2</li>
<li><a
href="1b0c756bd6"><code>1b0c756</code></a>
Print <code>declare</code> and <code>export</code> keywords for nested
namespace (<a
href="https://redirect.github.com/prettier/prettier/issues/15249">#15249</a>)</li>
<li><a
href="b4082cb647"><code>b4082cb</code></a>
chore(deps): update babel to v7.22.10 (<a
href="https://redirect.github.com/prettier/prettier/issues/15236">#15236</a>)</li>
<li><a
href="91e850b2bd"><code>91e850b</code></a>
chore(deps): update dependency camelcase to v8 (<a
href="https://redirect.github.com/prettier/prettier/issues/15245">#15245</a>)</li>
<li><a
href="f24132eda3"><code>f24132e</code></a>
Make chalk/assert shim a Proxy (<a
href="https://redirect.github.com/prettier/prettier/issues/15234">#15234</a>)</li>
<li><a
href="e22a5516f5"><code>e22a551</code></a>
chore(deps): update dependency <code>@​babel/parser</code> to v7.22.10
(<a
href="https://redirect.github.com/prettier/prettier/issues/15237">#15237</a>)</li>
<li><a
href="fbe46aa74a"><code>fbe46aa</code></a>
chore(deps): update dependency <code>@​angular/compiler</code> to
v16.2.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15240">#15240</a>)</li>
<li><a
href="7ecdbf7bc4"><code>7ecdbf7</code></a>
chore(deps): update typescript-eslint to v6.3.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15244">#15244</a>)</li>
<li><a
href="fb55780393"><code>fb55780</code></a>
chore(deps): update dependency eslint to v8.47.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15242">#15242</a>)</li>
<li><a
href="fde937d7b4"><code>fde937d</code></a>
chore(deps): update dependency hermes-parser to v0.15.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/15239">#15239</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/prettier/prettier/compare/3.0.1...3.0.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=3.0.1&new-version=3.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-22 13:55:46 -05:00
dependabot[bot]
f312b0bcce chore(deps-dev): Bump @types/node from 20.5.0 to 20.5.1 in /node (#423)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.5.0 to 20.5.1.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.5.0&new-version=20.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-22 13:55:38 -05:00
Muhammad Azeez
6102a99d98 fix(dotnet): typo in HostFunction constructor that prevents setting Host Function namespace (#418)
The only interesting part is this:

ba1baef9fb/dotnet/src/Extism.Sdk/HostFunction.cs (L68)
2023-08-15 20:05:37 +03:00
zach
b6f2e845d9 fix(runtime): register all host function imports (#419)
Fixes #417
2023-08-15 10:02:30 -07:00
dependabot[bot]
d1137fa739 chore(deps-dev): Bump @types/node from 20.4.8 to 20.5.0 in /node (#415)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.4.8 to 20.5.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.4.8&new-version=20.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-15 09:01:50 -07:00
dependabot[bot]
40a42882ba chore(deps-dev): Bump ex_doc from 0.30.4 to 0.30.5 in /elixir (#416)
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.30.4 to
0.30.5.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md">ex_doc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.30.5 (2023-08-12)</h2>
<ul>
<li>Bug fixes
<ul>
<li>Fix style for code in headers</li>
<li>Fix search data generation for Erlang/OTP</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7aa3fd9e8e"><code>7aa3fd9</code></a>
Release v0.30.5</li>
<li><a
href="feaf41c132"><code>feaf41c</code></a>
Do not style headers as links</li>
<li><a
href="4114bbfd1d"><code>4114bbf</code></a>
Fix generating search_data.json for undocumented Erlang functions</li>
<li>See full diff in <a
href="https://github.com/elixir-lang/ex_doc/compare/v0.30.4...v0.30.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ex_doc&package-manager=hex&previous-version=0.30.4&new-version=0.30.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-15 09:01:39 -07:00
Doğu Us
889ec39e4d refactor(zig)!: Simplify JSON stringifying (#414)
Uses `std.json.ArrayHashMap` for stringifying.

# Breaking Changes
* Plugin.setConfig's `config` parameter's type changed to
`std.json.ArrayHashMap([]const u8)`
* WasmUrl's `header` field's type changed to
`std.json.ArrayHashMap([]const u8)`
* Manifest's `config` and `allowed_path` fields' types changed to
`std.json.ArrayHashMap([]const u8)`
2023-08-11 20:10:30 -07:00
zach
fa909fd53d fix(rust): ensure InternalExt is exported (#413)
Also adds a test that uses `InternalExt` in the host function
2023-08-10 18:31:02 -07:00
dependabot[bot]
8dd4992633 chore(deps-dev): Bump @types/node from 20.4.5 to 20.4.8 in /node (#408)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.4.5 to 20.4.8.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.4.5&new-version=20.4.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-08 21:54:36 -05:00
dependabot[bot]
cfc9fb06a4 chore(deps-dev): Bump prettier from 3.0.0 to 3.0.1 in /node (#409)
Bumps [prettier](https://github.com/prettier/prettier) from 3.0.0 to
3.0.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>3.0.1</h2>
<p>🔗 <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md#301">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>3.0.1</h1>
<p><a
href="https://github.com/prettier/prettier/compare/3.0.0...3.0.1">diff</a></p>
<h4>Fix cursor positioning for a special case (<a
href="https://redirect.github.com/prettier/prettier/pull/14812">#14812</a>
by <a href="https://github.com/fisker"><code>@​fisker</code></a>)</h4>
<!-- raw HTML omitted -->
<pre lang="js"><code>// &lt;|&gt; is the cursor position
<p>/* Input */
// All messages are represented in JSON.
// So, the prettier.py controls a subprocess which spawns &quot;node
{this_file}&quot;.
import {&lt;|&gt;  } from &quot;fs&quot;</p>
<p>/* Prettier 3.0.0 */
// All messages are represented in JSON.
// So, the prettier.py &lt;|&gt;controls a subprocess which spawns
&quot;node {this_file}&quot;.
import {} from &quot;fs&quot;</p>
<p>/* Prettier 3.0.1 */
// All messages are represented in JSON.
// So, the prettier.py controls a subprocess which spawns &quot;node
{this_file}&quot;.
import {&lt;|&gt;} from &quot;fs&quot;
</code></pre></p>
<h4>Fix plugins/estree.d.ts to make it a module (<a
href="https://redirect.github.com/prettier/prettier/pull/15018">#15018</a>
by <a
href="https://github.com/kingyue737"><code>@​kingyue737</code></a>)</h4>
<p>Add <code>export {}</code> in <code>plugins/estree.d.ts</code> to fix
the &quot;File is not a module&quot; error</p>
<h4>Add parenthesis around leading multiline comment in return statement
(<a
href="https://redirect.github.com/prettier/prettier/pull/15037">#15037</a>
by <a href="https://github.com/auvred"><code>@​auvred</code></a>)</h4>
<!-- raw HTML omitted -->
<pre lang="jsx"><code>// Input
function fn() {
  return (
    /**
     * @type {...}
     */ expresssion
  )
}
<p>// Prettier 3.0.0
function fn() {
return /**</p>
<ul>
<li><a href="https://github.com/type"><code>@​type</code></a> {...}
*/ expresssion;
}</li>
</ul>
<p>&lt;/tr&gt;&lt;/table&gt;
</code></pre></p>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="afee0db664"><code>afee0db</code></a>
Release 3.0.1</li>
<li><a
href="c3d53dce7e"><code>c3d53dc</code></a>
Fix <code>runYarn</code> function in release script (<a
href="https://redirect.github.com/prettier/prettier/issues/15200">#15200</a>)</li>
<li><a
href="825425c57f"><code>825425c</code></a>
chore(deps): update dependency eslint-plugin-import to v2.28.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15184">#15184</a>)</li>
<li><a
href="448217df22"><code>448217d</code></a>
chore(deps): update dependency eslint to v8.46.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15182">#15182</a>)</li>
<li><a
href="f35e9e6bab"><code>f35e9e6</code></a>
chore(deps): update dependency <code>@​angular/compiler</code> to
v16.1.7 (<a
href="https://redirect.github.com/prettier/prettier/issues/15173">#15173</a>)</li>
<li><a
href="d14e893147"><code>d14e893</code></a>
chore(deps): update dependency c8 to v8.0.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/15174">#15174</a>)</li>
<li><a
href="c44d4b761e"><code>c44d4b7</code></a>
chore(deps): update dependency eslint-plugin-react to v7.33.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/15176">#15176</a>)</li>
<li><a
href="57e8c87506"><code>57e8c87</code></a>
chore(deps): update dependency esbuild to v0.18.17 (<a
href="https://redirect.github.com/prettier/prettier/issues/15175">#15175</a>)</li>
<li><a
href="36c3738aa9"><code>36c3738</code></a>
chore(deps): update dependency eslint-plugin-unicorn to v48.0.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/15177">#15177</a>)</li>
<li><a
href="2d274dfcdd"><code>2d274df</code></a>
chore(deps): update dependency flow-parser to v0.213.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/15178">#15178</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/prettier/prettier/compare/3.0.0...3.0.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=3.0.0&new-version=3.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-08 21:54:22 -05:00
dependabot[bot]
0e1a8677c5 chore(deps-dev): Bump ex_doc from 0.30.3 to 0.30.4 in /elixir (#410)
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.30.3 to
0.30.4.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md">ex_doc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.30.4 (2023-08-03)</h2>
<ul>
<li>Bug fixes
<ul>
<li>Fix style for anchors in headers</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a67fed176c"><code>a67fed1</code></a>
Release v0.30.4</li>
<li><a
href="eb6bbda3a2"><code>eb6bbda</code></a>
Bump word-wrap from 1.2.3 to 1.2.4 in /assets (<a
href="https://redirect.github.com/elixir-lang/ex_doc/issues/1742">#1742</a>)</li>
<li><a
href="2b5bbb3eb1"><code>2b5bbb3</code></a>
Update assets</li>
<li><a
href="be43c5a939"><code>be43c5a</code></a>
fix generation of livebook paths to handle omitted '.html' correctly (<a
href="https://redirect.github.com/elixir-lang/ex_doc/issues/1741">#1741</a>)</li>
<li><a
href="6c3afe5472"><code>6c3afe5</code></a>
Update assets</li>
<li>See full diff in <a
href="https://github.com/elixir-lang/ex_doc/compare/v0.30.3...v0.30.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ex_doc&package-manager=hex&previous-version=0.30.3&new-version=0.30.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-08 21:54:12 -05:00
zach
d80584600b refactor: Simplify runtime handling (#411)
It seems like our runtime initialization process is a little too
aggressive, this PR scales it back to initialize the runtime once if it
exists and only reinitializes when `_start` is called. This prevents
globals from being wiped out between plugin calls.

- Removes Runtime::cleanup
- Only initializes runtime once, or if `_start` is called
- Improves Haskell reactor support

See https://github.com/extism/go-sdk/pull/11 for the go-sdk PR.
2023-08-08 14:12:09 -07:00
zach
07623ef2da fix: avoid timeout errors outside of extism_plugin_call (#407)
- Delays instantiation to right before a call by using `instantiate_pre`
instead. This fixes an issue with the assemblyscript PDK.
- Makes timeouts only apply to calls
- Also bumps the wasmtime lower-bounds to 10.0, because the return type
of the epoch callback has changed
2023-08-04 13:44:24 -07:00
zach
c7c7f9d024 chore: update wasmtime bounds to include 11.0 (#405) 2023-08-01 11:12:02 -07:00
zach
3420960d7f chore(zig): use LazyPath in build.zig (#406) 2023-08-01 10:28:53 -07:00
zach
baa060d062 feat: Haskell host functions (#400) 2023-07-31 16:52:01 -07:00
dependabot[bot]
3219d79a8f chore(deps-dev): Bump @types/node from 20.4.2 to 20.4.5 in /node (#404)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.4.2 to 20.4.5.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.4.2&new-version=20.4.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-31 14:59:52 -05:00
dependabot[bot]
a3053a9ecc chore(deps-dev): Bump jest from 29.6.1 to 29.6.2 in /node (#403)
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest)
from 29.6.1 to 29.6.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/releases">jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.6.2</h2>
<h2>Fixes</h2>
<ul>
<li><code>[jest-circus]</code> Fix snapshot matchers in concurrent tests
when nr of tests exceeds <code>maxConcurrency</code> (<a
href="https://redirect.github.com/jestjs/jest/pull/14335">#14335</a>)</li>
<li><code>[@jest/core]</code> When running global setup and teardown, do
not try to change the <code>message</code> property of the thrown error
object when the <code>message</code> property is unwritable (<a
href="https://redirect.github.com/jestjs/jest/pull/14113">#14113</a>)</li>
<li><code>[jest-snapshot]</code> Move <code>@types/prettier</code> from
<code>dependencies</code> to <code>devDependencies</code> (<a
href="https://redirect.github.com/jestjs/jest/pull/14328">#14328</a>)</li>
<li><code>[jest-snapshot]</code> Throw an explicit error if Prettier v3
is used (<a
href="https://redirect.github.com/jestjs/jest/pull/14367">#14367</a>)</li>
<li><code>[jest-reporters]</code> Add &quot;skipped&quot; and
&quot;todo&quot; symbols to Github Actions Reporter (<a
href="https://redirect.github.com/jestjs/jest/pull/14309">#14309</a>)</li>
</ul>
<h2>Chore &amp; Maintenance</h2>
<ul>
<li><code>[@jest/core]</code> Use <code>pluralize</code> from
<code>jest-util</code> rather than own internal (<a
href="https://redirect.github.com/jestjs/jest/pull/14322">#14322</a>)</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Kloen"><code>@​Kloen</code></a> made
their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14328">jestjs/jest#14328</a></li>
<li><a href="https://github.com/eryue0220"><code>@​eryue0220</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14322">jestjs/jest#14322</a></li>
<li><a
href="https://github.com/david-szabo97"><code>@​david-szabo97</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14113">jestjs/jest#14113</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jestjs/jest/compare/v29.6.1...v29.6.2">https://github.com/jestjs/jest/compare/v29.6.1...v29.6.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jestjs/jest/blob/main/CHANGELOG.md">jest's
changelog</a>.</em></p>
<blockquote>
<h2>29.6.2</h2>
<h3>Fixes</h3>
<ul>
<li><code>[jest-circus]</code> Fix snapshot matchers in concurrent tests
when nr of tests exceeds <code>maxConcurrency</code> (<a
href="https://redirect.github.com/jestjs/jest/pull/14335">#14335</a>)</li>
<li><code>[@jest/core]</code> When running global setup and teardown, do
not try to change the <code>message</code> property of the thrown error
object when the <code>message</code> property is unwritable (<a
href="https://redirect.github.com/jestjs/jest/pull/14113">#14113</a>)</li>
<li><code>[jest-snapshot]</code> Move <code>@types/prettier</code> from
<code>dependencies</code> to <code>devDependencies</code> (<a
href="https://redirect.github.com/jestjs/jest/pull/14328">#14328</a>)</li>
<li><code>[jest-snapshot]</code> Throw an explicit error if Prettier v3
is used (<a
href="https://redirect.github.com/jestjs/jest/pull/14367">#14367</a>)</li>
<li><code>[jest-reporters]</code> Add &quot;skipped&quot; and
&quot;todo&quot; symbols to Github Actions Reporter (<a
href="https://redirect.github.com/jestjs/jest/pull/14309">#14309</a>)</li>
</ul>
<h3>Chore &amp; Maintenance</h3>
<ul>
<li><code>[@jest/core]</code> Use <code>pluralize</code> from
<code>jest-util</code> rather than own internal (<a
href="https://redirect.github.com/jestjs/jest/pull/14322">#14322</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0fd5b1c375"><code>0fd5b1c</code></a>
v29.6.2</li>
<li>See full diff in <a
href="https://github.com/facebook/jest/commits/v29.6.2/packages/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jest&package-manager=npm_and_yarn&previous-version=29.6.1&new-version=29.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-31 14:59:43 -05:00
dependabot[bot]
41450a03a9 chore(deps-dev): Update minitest requirement from ~> 5.18.0 to ~> 5.19.0 in /ruby (#402)
Updates the requirements on
[minitest](https://github.com/minitest/minitest) to permit the latest
version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/minitest/minitest/blob/master/History.rdoc">minitest's
changelog</a>.</em></p>
<blockquote>
<p>=== 5.19.0 / 2023-07-26</p>
<ul>
<li>
<p>2 minor enhancements:</p>
<ul>
<li>Add metadata lazy accessor to Runnable / Result. (matteeyah)</li>
<li>Only load minitest/unit (aka ancient MiniTest compatibility layer)
if ENV[&quot;MT_COMPAT&quot;]</li>
</ul>
</li>
<li>
<p>1 bug fix:</p>
<ul>
<li>Minitest::TestTask enthusiastically added itself to default.
(ParadoxV5)</li>
</ul>
</li>
</ul>
<p>=== 5.18.1 / 2023-06-16</p>
<ul>
<li>
<p>3 bug fixes:</p>
<ul>
<li>Avoid extra string allocations when filtering tests.
(tenderlove)</li>
<li>Only mention deprecated ENV['N'] if it is an integer string.</li>
<li>Push up test_order to Minitest::Runnable to fix minitest/hell.
(koic)</li>
</ul>
</li>
</ul>
<p>=== 5.18.0 / 2023-03-04</p>
<ul>
<li>
<p>2 major enhancements:</p>
<ul>
<li>Added assert_pattern &amp; refute_pattern for pattern matching.
(flavorjones)</li>
<li>Added matching must_pattern_match &amp; wont_pattern_match to
minitest/spec.</li>
</ul>
</li>
<li>
<p>1 bug fix:</p>
<ul>
<li>Support the new message format of NameError in Ruby 3.3 (mame)</li>
</ul>
</li>
</ul>
<p>=== 5.17.0 / 2022-12-31</p>
<ul>
<li>
<p>1 minor enhancement:</p>
<ul>
<li>Refactor setup hooks into a SETUP_METHODS constant. (MSP-Greg)</li>
</ul>
</li>
<li>
<p>3 bug fixes:</p>
<ul>
<li>Fix kwargs for Mock calls to delegator. (blowmage)</li>
<li>Fix kwargs for expectations. (bobmazanec, blowmage)</li>
<li>Remove check for .b method. (tenderlove)</li>
</ul>
</li>
</ul>
<p>=== 5.16.3 / 2022-08-17</p>
<ul>
<li>
<p>2 bug fixes:</p>
<ul>
<li>Fixed exception sanitization by removing TypeError restriction on
rescue.</li>
<li>Use A instead of deprecated TESTOPTS in rake test:slow.
(davidstosik)</li>
</ul>
</li>
</ul>
<p>=== 5.16.2 / 2022-07-03</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="96a9972916"><code>96a9972</code></a>
prepped for release</li>
<li><a
href="de802824b3"><code>de80282</code></a>
+ Add metadata lazy accessor to Runnable / Result. (matteeyah)</li>
<li><a
href="47959978df"><code>4795997</code></a>
- Minitest::TestTask enthusiastically added itself to default.
(ParadoxV5)</li>
<li><a
href="a2c6c18570"><code>a2c6c18</code></a>
+ Only load minitest/unit (aka ancient MiniTest compatibility layer) if
ENV[&quot;...</li>
<li><a
href="5f05692630"><code>5f05692</code></a>
Replace 'MiniTest' with 'Minitest' in example code. (sambostock)</li>
<li><a
href="31da3c6b8d"><code>31da3c6</code></a>
prepped for release</li>
<li><a
href="a90720a6c7"><code>a90720a</code></a>
Removed 2.6 from CI.</li>
<li><a
href="ca42951bbf"><code>ca42951</code></a>
- Avoid extra string allocations when filtering tests. (tenderlove)</li>
<li><a
href="e6f4a85e95"><code>e6f4a85</code></a>
- Only mention deprecated ENV['N'] if it is an integer string.</li>
<li><a
href="a9fa045044"><code>a9fa045</code></a>
- Push up test_order to Minitest::Runnable to fix minitest/hell.
(koic)</li>
<li>Additional commits viewable in <a
href="https://github.com/minitest/minitest/compare/v5.18.0...v5.19.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-31 14:59:19 -05:00
zach
26b34ed906 fix: Update more SDKs to store a reference to host functions in the Plugin type (#401)
Similar to https://github.com/extism/extism/pull/399
2023-07-31 11:25:47 -07:00
zach
ab4995dac2 fix(python): store reference to host functions on Plugin (#399)
This should fix the issue @neuronicnobody ran into with a segfault
depending on the scope of the host function definition
2023-07-28 15:08:10 -07:00
zach
3da526286e feat: Implement parts of the extism runtime in WebAssembly (#384)
This PR adds the `kernel` directory which contains a port of the Extism
memory allocator compiled to WebAssembly and removes
`runtime/src/memory.rs` completely.

Being able to re-use memory functions as a WASM module allows us to
begin to experiment with porting Extism to new runtimes!

This is in a draft state while I'm verifying some of these changes.
2023-07-27 11:31:23 -07:00
dependabot[bot]
618c132194 chore(deps-dev): Bump word-wrap from 1.2.3 to 1.2.4 in /browser (#394)
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3
to 1.2.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jonschlinkert/word-wrap/releases">word-wrap's
releases</a>.</em></p>
<blockquote>
<h2>1.2.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Remove default indent by <a
href="https://github.com/mohd-akram"><code>@​mohd-akram</code></a> in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/24">jonschlinkert/word-wrap#24</a></li>
<li>🔒fix: CVE 2023 26115 (2) by <a
href="https://github.com/OlafConijn"><code>@​OlafConijn</code></a> in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/41">jonschlinkert/word-wrap#41</a></li>
<li>🔒 fix: CVE-2023-26115 by <a
href="https://github.com/aashutoshrathi"><code>@​aashutoshrathi</code></a>
in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/33">jonschlinkert/word-wrap#33</a></li>
<li>chore: publish workflow by <a
href="https://github.com/OlafConijn"><code>@​OlafConijn</code></a> in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/42">jonschlinkert/word-wrap#42</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/mohd-akram"><code>@​mohd-akram</code></a> made
their first contribution in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/24">jonschlinkert/word-wrap#24</a></li>
<li><a
href="https://github.com/OlafConijn"><code>@​OlafConijn</code></a> made
their first contribution in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/41">jonschlinkert/word-wrap#41</a></li>
<li><a
href="https://github.com/aashutoshrathi"><code>@​aashutoshrathi</code></a>
made their first contribution in <a
href="https://redirect.github.com/jonschlinkert/word-wrap/pull/33">jonschlinkert/word-wrap#33</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4">https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f64b188c72"><code>f64b188</code></a>
run verb to generate README</li>
<li><a
href="03ea08256b"><code>03ea082</code></a>
Merge pull request <a
href="https://redirect.github.com/jonschlinkert/word-wrap/issues/42">#42</a>
from jonschlinkert/chore/publish-workflow</li>
<li><a
href="420dce9a24"><code>420dce9</code></a>
Merge pull request <a
href="https://redirect.github.com/jonschlinkert/word-wrap/issues/41">#41</a>
from jonschlinkert/fix/CVE-2023-26115-2</li>
<li><a
href="bfa694edf5"><code>bfa694e</code></a>
Update .github/workflows/publish.yml</li>
<li><a
href="ace0b3c78f"><code>ace0b3c</code></a>
chore: bump version to 1.2.4</li>
<li><a
href="6fd7275946"><code>6fd7275</code></a>
chore: add publish workflow</li>
<li><a
href="30d6daf60f"><code>30d6daf</code></a>
chore: fix test</li>
<li><a
href="655929cabe"><code>655929c</code></a>
chore: remove package-lock</li>
<li><a
href="49e08bbc32"><code>49e08bb</code></a>
chore: added an additional testcase</li>
<li><a
href="9f626935f3"><code>9f62693</code></a>
fix: cve 2023-26115</li>
<li>Additional commits viewable in <a
href="https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=word-wrap&package-manager=npm_and_yarn&previous-version=1.2.3&new-version=1.2.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/extism/extism/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-20 08:30:36 -05:00
dependabot[bot]
f4aa139ece chore(deps-dev): Bump ex_doc from 0.30.1 to 0.30.3 in /elixir (#390)
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.30.1 to
0.30.3.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md">ex_doc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.30.3 (2023-07-15)</h2>
<ul>
<li>
<p>Enhancements</p>
<ul>
<li>Compress search index before storing in local storage</li>
</ul>
</li>
<li>
<p>Bug fixes</p>
<ul>
<li>Fix styling for headers on cheatsheets and small screens</li>
</ul>
</li>
</ul>
<h2>v0.30.2 (2023-07-11)</h2>
<ul>
<li>Bug fixes
<ul>
<li>Fix escaping in <code>search_data.json</code></li>
<li>Skip vega-lite code blocks in <code>search_data.json</code></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/elixir-lang/ex_doc/commits">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ex_doc&package-manager=hex&previous-version=0.30.1&new-version=0.30.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 11:06:03 -05:00
dependabot[bot]
4548480c0b chore(deps-dev): Bump @types/node from 20.4.1 to 20.4.2 in /node (#391)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.4.1 to 20.4.2.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.4.1&new-version=20.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 11:05:53 -05:00
dependabot[bot]
7db38fd10e chore(deps-dev): Bump @types/jest from 29.5.2 to 29.5.3 in /node (#392)
Bumps
[@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest)
from 29.5.2 to 29.5.3.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/jest&package-manager=npm_and_yarn&previous-version=29.5.2&new-version=29.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 11:05:44 -05:00
dependabot[bot]
58f7d5fa95 chore(deps): Bump tough-cookie from 4.1.2 to 4.1.3 in /browser (#389)
Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from
4.1.2 to 4.1.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/salesforce/tough-cookie/releases">tough-cookie's
releases</a>.</em></p>
<blockquote>
<h2>4.1.3</h2>
<p>Security fix for Prototype Pollution discovery in <a
href="https://redirect.github.com/salesforce/tough-cookie/issues/282">#282</a>.
This is a minor release, although output from the <code>inspect</code>
utility is affected by this change, we felt this change was important
enough to be pushed into the next patch.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4ff4d29f6c"><code>4ff4d29</code></a>
4.1.3 release preparation, update the package and lib/version to 4.1.3.
(<a
href="https://redirect.github.com/salesforce/tough-cookie/issues/284">#284</a>)</li>
<li><a
href="12d474791b"><code>12d4747</code></a>
Prevent prototype pollution in cookie memstore (<a
href="https://redirect.github.com/salesforce/tough-cookie/issues/283">#283</a>)</li>
<li><a
href="f06b72d1d4"><code>f06b72d</code></a>
Fix documentation for store.findCookies, missing allowSpecialUseDomain
proper...</li>
<li>See full diff in <a
href="https://github.com/salesforce/tough-cookie/compare/v4.1.2...v4.1.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=tough-cookie&package-manager=npm_and_yarn&previous-version=4.1.2&new-version=4.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/extism/extism/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:57:38 -05:00
dependabot[bot]
f10539a431 chore(deps-dev): Bump ex_doc from 0.29.4 to 0.30.1 in /elixir (#388)
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.29.4 to
0.30.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md">ex_doc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.30.1 (2023-07-07)</h2>
<ul>
<li>Bug fixes
<ul>
<li>Fix styling for headers on cheatsheets and small screens</li>
</ul>
</li>
</ul>
<h2>v0.30.0 (2023-07-07)</h2>
<ul>
<li>
<p>Enhancements</p>
<ul>
<li>Support tabsets (see the README for more information)</li>
<li>Improve search results and indexing by storing more data and
metadata</li>
<li>Warn on invalid references in links</li>
<li>Strike-through deprecated items on autocompletion</li>
<li>Add source URL link to API reference page</li>
<li>Allow multiple extra files with the same name by generating unique
names in case of conflicts</li>
</ul>
</li>
<li>
<p>Bug fixes</p>
<ul>
<li>Fix rendering of large code blocks in admonition texts</li>
<li>Do not log errors on module mismatch in case-insensitive file
systems</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0d2f4dc62d"><code>0d2f4dc</code></a>
Release v0.30.1</li>
<li><a
href="0e9349ef73"><code>0e9349e</code></a>
Update assets</li>
<li><a
href="11dda904d2"><code>11dda90</code></a>
Fix bugs in headers</li>
<li><a
href="2ffaa811b0"><code>2ffaa81</code></a>
Release v0.30.0</li>
<li><a
href="964a22658c"><code>964a226</code></a>
Update assets</li>
<li><a
href="091fb70432"><code>091fb70</code></a>
Revert &quot;Make dummy assets change&quot;</li>
<li><a
href="948825d73f"><code>948825d</code></a>
Update assets</li>
<li><a
href="7e661dc589"><code>7e661dc</code></a>
Make dummy assets change</li>
<li><a
href="7d3d195acb"><code>7d3d195</code></a>
Update assets on CI (<a
href="https://redirect.github.com/elixir-lang/ex_doc/issues/1731">#1731</a>)</li>
<li><a
href="c54c5e63d9"><code>c54c5e6</code></a>
Remove padding on anchor</li>
<li>Additional commits viewable in <a
href="https://github.com/elixir-lang/ex_doc/compare/v0.29.4...v0.30.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ex_doc&package-manager=hex&previous-version=0.29.4&new-version=0.30.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:57:25 -05:00
dependabot[bot]
e26e6d2da1 chore(deps-dev): Bump @types/node from 20.3.3 to 20.4.1 in /node (#387)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.3.3 to 20.4.1.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.3.3&new-version=20.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:57:17 -05:00
dependabot[bot]
70a9a3da66 chore(deps-dev): Bump prettier from 2.8.8 to 3.0.0 in /node (#386)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to
3.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>3.0.0</h2>
<p><a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.6...3.0.0">diff</a></p>
<p>🔗 <a href="https://prettier.io/blog/2023/07/05/3.0.0.html">Release
note</a></p>
<h2>3.0.0-alpha.6</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>.d.ts</code> files of plugins to use <code>export
default ...</code> by <a
href="https://github.com/fisker"><code>@​fisker</code></a> in <a
href="https://redirect.github.com/prettier/prettier/pull/14435">prettier/prettier#14435</a></li>
</ul>
<p>Other changes since v2, see <a
href="https://github.com/prettier/prettier/releases/tag/3.0.0-alpha.1"><code>3.0.0-alpha.1</code>
release notes</a></p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.5...3.0.0-alpha.6">https://github.com/prettier/prettier/compare/3.0.0-alpha.5...3.0.0-alpha.6</a></p>
<h2>3.0.0-alpha.5</h2>
<h2>What's Changed</h2>
<ul>
<li>Add <code>.d.ts</code> files by <a
href="https://github.com/sosukesuzuki"><code>@​sosukesuzuki</code></a>
in <a
href="https://redirect.github.com/prettier/prettier/pull/14212">prettier/prettier#14212</a></li>
<li>Support TypeScript 5 via <code>babel-ts</code> parser by <a
href="https://github.com/fisker"><code>@​fisker</code></a> in <a
href="https://redirect.github.com/prettier/prettier/pull/14391">prettier/prettier#14391</a></li>
</ul>
<p>Other changes since v2, see <a
href="https://github.com/prettier/prettier/releases/tag/3.0.0-alpha.1"><code>3.0.0-alpha.1</code>
release notes</a></p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.4...3.0.0-alpha.5">https://github.com/prettier/prettier/compare/3.0.0-alpha.4...3.0.0-alpha.5</a></p>
<h2>3.0.0-alpha.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Remove support for Flow comment types by <a
href="https://github.com/thorn0"><code>@​thorn0</code></a> in <a
href="https://redirect.github.com/prettier/prettier/pull/13687">prettier/prettier#13687</a></li>
<li>Make <code>resolveParser</code> work like v2 by <a
href="https://github.com/fisker"><code>@​fisker</code></a> in <a
href="https://redirect.github.com/prettier/prettier/pull/13732">prettier/prettier#13732</a></li>
<li>Add <code>__debug</code> apis to cjs version by <a
href="https://github.com/fisker"><code>@​fisker</code></a> in <a
href="https://redirect.github.com/prettier/prettier/pull/13731">prettier/prettier#13731</a></li>
</ul>
<p>Other changes since v2, see <a
href="https://github.com/prettier/prettier/releases/tag/3.0.0-alpha.1"><code>3.0.0-alpha.1</code>
release notes</a></p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.3...3.0.0-alpha.4">https://github.com/prettier/prettier/compare/3.0.0-alpha.3...3.0.0-alpha.4</a></p>
<h2>3.0.0-alpha.3</h2>
<ul>
<li>Fix <code>exports</code> field in <code>package.json</code>
file</li>
</ul>
<p>Other changes since v2, see <a
href="https://github.com/prettier/prettier/releases/tag/3.0.0-alpha.1"><code>3.0.0-alpha.1</code>
release notes</a></p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.2...3.0.0-alpha.3">https://github.com/prettier/prettier/compare/3.0.0-alpha.2...3.0.0-alpha.3</a></p>
<h2>3.0.0-alpha.2</h2>
<ul>
<li>Fix bundled <code>index.cjs</code> file</li>
</ul>
<p>Other changes since v2, see <a
href="https://github.com/prettier/prettier/releases/tag/3.0.0-alpha.1"><code>3.0.0-alpha.1</code>
release notes</a></p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.1...3.0.0-alpha.2">https://github.com/prettier/prettier/compare/3.0.0-alpha.1...3.0.0-alpha.2</a></p>
<h2>3.0.0-alpha.1</h2>
<p><strong>If you are a plugin developer, please try this version and
send us feedback! Feel free to ping <a
href="https://github.com/fisker"><code>@​fisker</code></a> if you have
any questions about v3 migration.</strong></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>3.0.0</h1>
<p><a
href="https://github.com/prettier/prettier/compare/3.0.0-alpha.6...3.0.0">diff</a></p>
<p>🔗 <a href="https://prettier.io/blog/2023/07/05/3.0.0.html">Release
Notes</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="186e0966b0"><code>186e096</code></a>
Release 3.0.0</li>
<li><a
href="44979b0a37"><code>44979b0</code></a>
Remove test step from release script (<a
href="https://redirect.github.com/prettier/prettier/issues/15011">#15011</a>)</li>
<li><a
href="e12afe89f3"><code>e12afe8</code></a>
Regenerate yarn.lock file (<a
href="https://redirect.github.com/prettier/prettier/issues/15010">#15010</a>)</li>
<li><a
href="db31fd602e"><code>db31fd6</code></a>
Regenerate yarn.lock file for website (<a
href="https://redirect.github.com/prettier/prettier/issues/15009">#15009</a>)</li>
<li><a
href="1a0d9ed800"><code>1a0d9ed</code></a>
chore(deps): update dependency cosmiconfig to v8.2.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/14901">#14901</a>)</li>
<li><a
href="25fa483e35"><code>25fa483</code></a>
chore(deps): update dependency typescript to v5.1.5 (<a
href="https://redirect.github.com/prettier/prettier/issues/14896">#14896</a>)</li>
<li><a
href="d0759650b8"><code>d075965</code></a>
chore(deps): update dependency webpack to v5.88.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/14994">#14994</a>)</li>
<li><a
href="d97f78db99"><code>d97f78d</code></a>
chore(deps): update dependency webpack to v5.88.1 (<a
href="https://redirect.github.com/prettier/prettier/issues/14995">#14995</a>)</li>
<li><a
href="f1ef433e98"><code>f1ef433</code></a>
chore(deps): update dependency flow-parser to v0.211.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15002">#15002</a>)</li>
<li><a
href="61804e2516"><code>61804e2</code></a>
chore(deps): update dependency espree to v9.6.0 (<a
href="https://redirect.github.com/prettier/prettier/issues/15000">#15000</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/prettier/prettier/compare/2.8.8...3.0.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=2.8.8&new-version=3.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:57:09 -05:00
dependabot[bot]
b86f6267f6 chore(deps-dev): Bump jest from 29.5.0 to 29.6.1 in /node (#385)
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest)
from 29.5.0 to 29.6.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/releases">jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.6.1</h2>
<h2>Fixes</h2>
<ul>
<li><code>[jest-circus]</code> Revert <a
href="https://redirect.github.com/jestjs/jest/pull/14110">#14110</a> as
it was a breaking change (<a
href="https://redirect.github.com/jestjs/jest/pull/14304">#14304</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jestjs/jest/compare/v29.6.0...v29.6.1">https://github.com/jestjs/jest/compare/v29.6.0...v29.6.1</a></p>
<h2>v29.6.0</h2>
<h2>Features</h2>
<ul>
<li><code>[jest-circus, jest-snapshot]</code> Add support for snapshot
matchers in concurrent tests (<a
href="https://redirect.github.com/jestjs/jest/pull/14139">#14139</a>)</li>
<li><code>[jest-cli]</code> Include type definitions to generated config
files (<a
href="https://redirect.github.com/facebook/jest/pull/14078">#14078</a>)</li>
<li><code>[jest-snapshot]</code> Support arrays as property matchers (<a
href="https://redirect.github.com/facebook/jest/pull/14025">#14025</a>)</li>
<li><code>[jest-core, jest-circus, jest-reporter, jest-runner]</code>
Added support for reporting about start individual test cases using
jest-circus (<a
href="https://redirect.github.com/jestjs/jest/pull/14174">#14174</a>)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><code>[jest-circus]</code> Prevent false test failures caused by
promise rejections handled asynchronously (<a
href="https://redirect.github.com/jestjs/jest/pull/14110">#14110</a>)</li>
<li><code>[jest-config]</code> Handle frozen config object (<a
href="https://redirect.github.com/facebook/jest/pull/14054">#14054</a>)</li>
<li><code>[jest-config]</code> Allow <code>coverageDirectory</code> and
<code>collectCoverageFrom</code> in project config (<a
href="https://redirect.github.com/jestjs/jest/pull/14180">#14180</a>)</li>
<li><code>[jest-core]</code> Always use workers in watch mode to avoid
crashes (<a
href="https://redirect.github.com/facebook/jest/pull/14059">#14059</a>).</li>
<li><code>[jest-environment-jsdom, jest-environment-node]</code> Fix
assignment of <code>customExportConditions</code> via
<code>testEnvironmentOptions</code> when custom env subclass defines a
default value (<a
href="https://redirect.github.com/facebook/jest/pull/13989">#13989</a>)</li>
<li><code>[jest-matcher-utils]</code> Fix copying value of inherited
getters (<a
href="https://redirect.github.com/facebook/jest/pull/14007">#14007</a>)</li>
<li><code>[jest-mock]</code> Tweak typings to allow
<code>jest.replaceProperty()</code> replace methods (<a
href="https://redirect.github.com/facebook/jest/pull/14008">#14008</a>)</li>
<li><code>[jest-mock]</code> Improve user input validation and error
messages of <code>spyOn</code> and <code>replaceProperty</code> methods
(<a
href="https://redirect.github.com/facebook/jest/pull/14087">#14087</a>)</li>
<li><code>[jest-runtime]</code> Bind
<code>jest.isolateModulesAsync</code> to <code>this</code> (<a
href="https://redirect.github.com/facebook/jest/pull/14083">#14083</a>)</li>
<li><code>[jest-runtime]</code> Forward <code>wrapperLength</code> to
the <code>Script</code> constructor as <code>columnOffset</code> for
accurate debugging (<a
href="https://redirect.github.com/facebook/jest/pull/14148">#14148</a>)</li>
<li><code>[jest-runtime]</code> Guard <code>_isMockFunction</code>
access with <code>in</code> (<a
href="https://redirect.github.com/facebook/jest/pull/14188">#14188</a>)</li>
<li><code>[jest-snapshot]</code> Fix a potential bug when not using
prettier and improve performance (<a
href="https://redirect.github.com/facebook/jest/pull/14036">#14036</a>)</li>
<li><code>[@jest/transform]</code> Do not instrument <code>.json</code>
modules (<a
href="https://redirect.github.com/facebook/jest/pull/14048">#14048</a>)</li>
<li><code>[jest-worker]</code> Restart a shut down worker before sending
it a task (<a
href="https://redirect.github.com/facebook/jest/pull/14015">#14015</a>)</li>
</ul>
<h2>Chore &amp; Maintenance</h2>
<ul>
<li><code>[*]</code> Update <code>semver</code> dependency to get
vulnerability fix (<a
href="https://redirect.github.com/jestjs/jest/pull/14262">#14262</a>)</li>
<li><code>[docs]</code> Updated documentation for the
<code>--runTestsByPath</code> CLI command (<a
href="https://redirect.github.com/facebook/jest/pull/14004">#14004</a>)</li>
<li><code>[docs]</code> Updated documentation regarding the synchronous
fallback when asynchronous code transforms are unavailable (<a
href="https://redirect.github.com/facebook/jest/pull/14056">#14056</a>)</li>
<li><code>[docs]</code> Update jest statistics of use and downloads in
website Index.</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/huntie"><code>@​huntie</code></a> made
their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/13989">jestjs/jest#13989</a></li>
<li><a href="https://github.com/liammulh"><code>@​liammulh</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14001">jestjs/jest#14001</a></li>
<li><a
href="https://github.com/BenceSzalai"><code>@​BenceSzalai</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14007">jestjs/jest#14007</a></li>
<li><a href="https://github.com/Mike-Dax"><code>@​Mike-Dax</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14056">jestjs/jest#14056</a></li>
<li><a
href="https://github.com/bakasmarius"><code>@​bakasmarius</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14025">jestjs/jest#14025</a></li>
<li><a
href="https://github.com/PeteTheHeat"><code>@​PeteTheHeat</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14015">jestjs/jest#14015</a></li>
<li><a
href="https://github.com/tjenkinson"><code>@​tjenkinson</code></a> made
their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14083">jestjs/jest#14083</a></li>
<li><a
href="https://github.com/soyjuanmacias"><code>@​soyjuanmacias</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14101">jestjs/jest#14101</a></li>
<li><a
href="https://github.com/bharathkalyans"><code>@​bharathkalyans</code></a>
made their first contribution in <a
href="https://redirect.github.com/jestjs/jest/pull/14154">jestjs/jest#14154</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jestjs/jest/blob/main/CHANGELOG.md">jest's
changelog</a>.</em></p>
<blockquote>
<h2>29.6.1</h2>
<h3>Fixes</h3>
<ul>
<li><code>[jest-circus]</code> Revert <a
href="https://redirect.github.com/jestjs/jest/pull/14110">#14110</a> as
it was a breaking change (<a
href="https://redirect.github.com/jestjs/jest/pull/14304">#14304</a>)</li>
</ul>
<h2>29.6.0</h2>
<h3>Features</h3>
<ul>
<li><code>[jest-circus, jest-snapshot]</code> Add support for snapshot
matchers in concurrent tests (<a
href="https://redirect.github.com/jestjs/jest/pull/14139">#14139</a>)</li>
<li><code>[jest-cli]</code> Include type definitions to generated config
files (<a
href="https://redirect.github.com/facebook/jest/pull/14078">#14078</a>)</li>
<li><code>[jest-snapshot]</code> Support arrays as property matchers (<a
href="https://redirect.github.com/facebook/jest/pull/14025">#14025</a>)</li>
<li><code>[jest-core, jest-circus, jest-reporter, jest-runner]</code>
Added support for reporting about start individual test cases using
jest-circus (<a
href="https://redirect.github.com/jestjs/jest/pull/14174">#14174</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>[jest-circus]</code> Prevent false test failures caused by
promise rejections handled asynchronously (<a
href="https://redirect.github.com/jestjs/jest/pull/14110">#14110</a>)</li>
<li><code>[jest-config]</code> Handle frozen config object (<a
href="https://redirect.github.com/facebook/jest/pull/14054">#14054</a>)</li>
<li><code>[jest-config]</code> Allow <code>coverageDirectory</code> and
<code>collectCoverageFrom</code> in project config (<a
href="https://redirect.github.com/jestjs/jest/pull/14180">#14180</a>)</li>
<li><code>[jest-core]</code> Always use workers in watch mode to avoid
crashes (<a
href="https://redirect.github.com/facebook/jest/pull/14059">#14059</a>).</li>
<li><code>[jest-environment-jsdom, jest-environment-node]</code> Fix
assignment of <code>customExportConditions</code> via
<code>testEnvironmentOptions</code> when custom env subclass defines a
default value (<a
href="https://redirect.github.com/facebook/jest/pull/13989">#13989</a>)</li>
<li><code>[jest-matcher-utils]</code> Fix copying value of inherited
getters (<a
href="https://redirect.github.com/facebook/jest/pull/14007">#14007</a>)</li>
<li><code>[jest-mock]</code> Tweak typings to allow
<code>jest.replaceProperty()</code> replace methods (<a
href="https://redirect.github.com/facebook/jest/pull/14008">#14008</a>)</li>
<li><code>[jest-mock]</code> Improve user input validation and error
messages of <code>spyOn</code> and <code>replaceProperty</code> methods
(<a
href="https://redirect.github.com/facebook/jest/pull/14087">#14087</a>)</li>
<li><code>[jest-runtime]</code> Bind
<code>jest.isolateModulesAsync</code> to <code>this</code> (<a
href="https://redirect.github.com/facebook/jest/pull/14083">#14083</a>)</li>
<li><code>[jest-runtime]</code> Forward <code>wrapperLength</code> to
the <code>Script</code> constructor as <code>columnOffset</code> for
accurate debugging (<a
href="https://redirect.github.com/facebook/jest/pull/14148">#14148</a>)</li>
<li><code>[jest-runtime]</code> Guard <code>_isMockFunction</code>
access with <code>in</code> (<a
href="https://redirect.github.com/facebook/jest/pull/14188">#14188</a>)</li>
<li><code>[jest-snapshot]</code> Fix a potential bug when not using
prettier and improve performance (<a
href="https://redirect.github.com/facebook/jest/pull/14036">#14036</a>)</li>
<li><code>[@jest/transform]</code> Do not instrument <code>.json</code>
modules (<a
href="https://redirect.github.com/facebook/jest/pull/14048">#14048</a>)</li>
<li><code>[jest-worker]</code> Restart a shut down worker before sending
it a task (<a
href="https://redirect.github.com/facebook/jest/pull/14015">#14015</a>)</li>
</ul>
<h3>Chore &amp; Maintenance</h3>
<ul>
<li><code>[*]</code> Update <code>semver</code> dependency to get
vulnerability fix (<a
href="https://redirect.github.com/jestjs/jest/pull/14262">#14262</a>)</li>
<li><code>[docs]</code> Updated documentation for the
<code>--runTestsByPath</code> CLI command (<a
href="https://redirect.github.com/facebook/jest/pull/14004">#14004</a>)</li>
<li><code>[docs]</code> Updated documentation regarding the synchronous
fallback when asynchronous code transforms are unavailable (<a
href="https://redirect.github.com/facebook/jest/pull/14056">#14056</a>)</li>
<li><code>[docs]</code> Update jest statistics of use and downloads in
website Index.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1f019afdcd"><code>1f019af</code></a>
v29.6.1</li>
<li><a
href="c1e5b8a38e"><code>c1e5b8a</code></a>
v29.6.0</li>
<li><a
href="6ffa48d1cd"><code>6ffa48d</code></a>
chore: upgrade TypeScript to v5 (<a
href="https://github.com/facebook/jest/tree/HEAD/packages/jest/issues/14155">#14155</a>)</li>
<li><a
href="a95eeb6c2c"><code>a95eeb6</code></a>
chore: update tsd runner (<a
href="https://github.com/facebook/jest/tree/HEAD/packages/jest/issues/14020">#14020</a>)</li>
<li>See full diff in <a
href="https://github.com/facebook/jest/commits/v29.6.1/packages/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jest&package-manager=npm_and_yarn&previous-version=29.5.0&new-version=29.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 10:57:00 -05:00
dependabot[bot]
6a49a6ee7c chore(deps-dev): Bump typescript from 5.1.3 to 5.1.6 in /node (#380)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.1.3
to 5.1.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Microsoft/TypeScript/releases">typescript's
releases</a>.</em></p>
<blockquote>
<h2>TypeScript 5.1.5</h2>
<p>For release notes, check out the <a
href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-1/">release
announcement</a>.</p>
<p>For the complete list of fixed issues, check out the</p>
<ul>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.0%22+is%3Aclosed+">fixed
issues query for Typescript v5.1.0 (Beta)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.1%22+is%3Aclosed+">fixed
issues query for Typescript v5.1.1 (RC)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.2%22+is%3Aclosed+">fixed
issues query for Typescript v5.1.2 (Stable)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.3%22+is%3Aclosed+">fixed
issues query for Typescript v5.1.3 (Stable)</a>.</li>
<li>(5.1.4 <a
href="https://redirect.github.com/microsoft/TypeScript/issues/53031#issuecomment-1610038922">intentionally
skipped</a>)</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.5%22+is%3Aclosed+">fixed
issues query for Typescript v5.1.5 (Stable)</a>.</li>
</ul>
<p>Downloads are available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/typescript">npm</a></li>
<li><a
href="https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild">NuGet
package</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/Microsoft/TypeScript/commits">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typescript&package-manager=npm_and_yarn&previous-version=5.1.3&new-version=5.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-06 16:57:01 -05:00
dependabot[bot]
3b5fea71d7 chore(deps-dev): Bump @types/node from 20.3.1 to 20.3.3 in /node (#381)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.3.1 to 20.3.3.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.3.1&new-version=20.3.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-06 16:56:54 -05:00
dependabot[bot]
c0ccf7558c chore(deps-dev): Bump ts-jest from 29.1.0 to 29.1.1 in /node (#382)
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.0 to
29.1.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/kulshekhar/ts-jest/releases">ts-jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.1.1</h2>
<p>Please refer to <a
href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">ts-jest's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/kulshekhar/ts-jest/compare/v29.1.0...v29.1.1">29.1.1</a>
(2023-06-23)</h2>
<h3>Security Fixes</h3>
<ul>
<li>bump <code>semver</code> to <code>7.5.3</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9670787b08"><code>9670787</code></a>
chore(release): 29.1.1 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4173">#4173</a>)</li>
<li><a
href="8c51d3252c"><code>8c51d32</code></a>
build(deps): Update actions/checkout digest to c85c95e (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4172">#4172</a>)</li>
<li><a
href="0f82024897"><code>0f82024</code></a>
build(deps): bump semver from 7.3.7 to 7.5.2 in /examples/react-app (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4170">#4170</a>)</li>
<li><a
href="431dca69cd"><code>431dca6</code></a>
build(deps): bump semver from 7.5.1 to 7.5.2 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4169">#4169</a>)</li>
<li><a
href="f4f7daeafd"><code>f4f7dae</code></a>
build(deps): Update <a
href="https://github.com/types"><code>@​types</code></a> packages (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4164">#4164</a>)</li>
<li><a
href="5e551acf30"><code>5e551ac</code></a>
build(deps): Update dependency <code>@​formatjs/ts-transformer</code> to
^3.13.3 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4165">#4165</a>)</li>
<li><a
href="2925d0e0ab"><code>2925d0e</code></a>
build(deps): Update dependency <code>@​formatjs/ts-transformer</code> to
^3.13.2 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4160">#4160</a>)</li>
<li><a
href="71c7786128"><code>71c7786</code></a>
build(deps): Update <a
href="https://github.com/types"><code>@​types</code></a> packages to
^5.59.9 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4159">#4159</a>)</li>
<li><a
href="099102e4a6"><code>099102e</code></a>
build(deps): Update dependency typescript to ~5.1.3 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4157">#4157</a>)</li>
<li><a
href="6e5a29414e"><code>6e5a294</code></a>
build(deps): Update dependency eslint to ^8.42.0 (<a
href="https://redirect.github.com/kulshekhar/ts-jest/issues/4158">#4158</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/kulshekhar/ts-jest/compare/v29.1.0...v29.1.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ts-jest&package-manager=npm_and_yarn&previous-version=29.1.0&new-version=29.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-06 16:56:46 -05:00
dependabot[bot]
35a6887e9f chore(deps): Bump rustler from 0.28.0 to 0.29.1 in /elixir (#383)
Bumps [rustler](https://github.com/rusterlium/rustler) from 0.28.0 to
0.29.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rusterlium/rustler/releases">rustler's
releases</a>.</em></p>
<blockquote>
<h2>rustler-0.29.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix NifTaggedEnum derived Encoder impl for named-field variants by
<a href="https://github.com/dylanburati"><code>@​dylanburati</code></a>
in <a
href="https://redirect.github.com/rusterlium/rustler/pull/547">rusterlium/rustler#547</a></li>
<li>Exclude directories from external resources to be compatible with
Elixir 1.15 by <a
href="https://github.com/adrienmo"><code>@​adrienmo</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/548">rusterlium/rustler#548</a></li>
<li>Remove cfg! directives in build.rs causing cross-compilation to fail
by <a
href="https://github.com/fabriziosestito"><code>@​fabriziosestito</code></a>
in <a
href="https://redirect.github.com/rusterlium/rustler/pull/555">rusterlium/rustler#555</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rusterlium/rustler/compare/rustler-0.28.0...rustler-0.29.0">https://github.com/rusterlium/rustler/compare/rustler-0.28.0...rustler-0.29.0</a></p>
<h2>rustler-0.29.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Make rustler_sys forward compatible by <a
href="https://github.com/filmor"><code>@​filmor</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/536">rusterlium/rustler#536</a></li>
<li>Add OTP26 to CI and bump rustler_sys by <a
href="https://github.com/filmor"><code>@​filmor</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/539">rusterlium/rustler#539</a></li>
<li>Introduce CI cache by <a
href="https://github.com/filmor"><code>@​filmor</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/541">rusterlium/rustler#541</a></li>
<li>Drop OTP23 entirely from CI and use -latest for all OS versions by
<a href="https://github.com/filmor"><code>@​filmor</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/542">rusterlium/rustler#542</a></li>
<li>Use features for minimal NIF version by <a
href="https://github.com/filmor"><code>@​filmor</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/537">rusterlium/rustler#537</a></li>
<li>Apply current NIF version for tests and raise default by <a
href="https://github.com/filmor"><code>@​filmor</code></a> in <a
href="https://redirect.github.com/rusterlium/rustler/pull/543">rusterlium/rustler#543</a></li>
<li>rustler: add a Rust type <code>ErlOption&lt;T&gt;</code> by <a
href="https://github.com/tatsuya6502"><code>@​tatsuya6502</code></a> in
<a
href="https://redirect.github.com/rusterlium/rustler/pull/507">rusterlium/rustler#507</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rusterlium/rustler/compare/rustler-0.28.0...rustler-0.29.0">https://github.com/rusterlium/rustler/compare/rustler-0.28.0...rustler-0.29.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rusterlium/rustler/blob/master/CHANGELOG.md">rustler's
changelog</a>.</em></p>
<blockquote>
<h2>[0.29.1] - 2023-06-30</h2>
<h3>Fixed</h3>
<ul>
<li>Exclude directories from external resources for compatibility with
Elixir 1.15
(<a
href="https://redirect.github.com/rusterlium/rustler/issues/548">#548</a>,
thanks <a
href="https://github.com/adrienmo"><code>@​adrienmo</code></a>)</li>
<li>Fix <code>NifTaggedEnum</code> derived <code>Encoder</code> impl for
named-field variants (<a
href="https://redirect.github.com/rusterlium/rustler/issues/547">#547</a>,
thanks <a
href="https://github.com/dylanburati"><code>@​dylanburati</code></a>)</li>
<li>Remove <code>cfg!</code> directives in build.rs causing
cross-compilation to fail (<a
href="https://redirect.github.com/rusterlium/rustler/issues/555">#555</a>,
thanks <a
href="https://github.com/fabriziosestito"><code>@​fabriziosestito</code></a>)</li>
</ul>
<h2>[0.29.0] - 2023-06-22</h2>
<h3>Added</h3>
<ul>
<li><code>ErlOption&lt;T&gt;</code> to provide an ergonomic option type
for Erlang (<a
href="https://redirect.github.com/rusterlium/rustler/issues/507">#507</a>,
thanks <a
href="https://github.com/tatsuya6502"><code>@​tatsuya6502</code></a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Use Cargo features to define the NIF version level (<a
href="https://redirect.github.com/rusterlium/rustler/issues/537">#537</a>),
deprecating
<code>RUSTLER_NIF_VERSION</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b817a6829a"><code>b817a68</code></a>
(release) 0.29.1</li>
<li><a
href="2e2e9248f0"><code>2e2e924</code></a>
Update changelog</li>
<li><a
href="9cfdcfc47a"><code>9cfdcfc</code></a>
use env variables instead of cfg! (<a
href="https://redirect.github.com/rusterlium/rustler/issues/555">#555</a>)</li>
<li><a
href="ea132ea08a"><code>ea132ea</code></a>
Fix NifTaggedEnum derived Encoder impl for named-field variants (<a
href="https://redirect.github.com/rusterlium/rustler/issues/547">#547</a>)</li>
<li><a
href="2cbc53ac3a"><code>2cbc53a</code></a>
Exclude directories from external resources (<a
href="https://redirect.github.com/rusterlium/rustler/issues/548">#548</a>)</li>
<li><a
href="78f7477705"><code>78f7477</code></a>
Roll changelog over</li>
<li><a
href="016e35bf8f"><code>016e35b</code></a>
Bump rustler_sys for feature-based NIF level selection</li>
<li><a
href="95d6961b29"><code>95d6961</code></a>
Make rustler depend on rustler_sys with features</li>
<li><a
href="680126bd61"><code>680126b</code></a>
(release) 0.29.0</li>
<li><a
href="d8aa66d976"><code>d8aa66d</code></a>
Merge pull request <a
href="https://redirect.github.com/rusterlium/rustler/issues/507">#507</a>
from tatsuya6502/erl-option</li>
<li>Additional commits viewable in <a
href="https://github.com/rusterlium/rustler/compare/rustler-0.28.0...rustler-0.29.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rustler&package-manager=hex&previous-version=0.28.0&new-version=0.29.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-06 16:56:37 -05:00
Doğu Us
81e51fb059 fix: update for latest Zig (#379) 2023-07-01 10:37:00 -07:00
zach
f606ab619f chore: use a range for wasmtime dependency version (#375)
Currently wasmtime `8.0.0` - `10.0.0` are compatible with
`extism-runtime`, in the interest of remaining compatible with as many
applications as possible, this PR updates the wasmtime version
requirement from a single version to a range of acceptable versions.
2023-06-20 15:34:01 -07:00
dependabot[bot]
c78104a846 chore(deps-dev): Bump @types/node from 20.3.0 to 20.3.1 in /node (#371)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.3.0 to 20.3.1.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.3.0&new-version=20.3.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-20 17:29:32 -05:00
dependabot[bot]
59101d80a6 chore(deps-dev): Bump @types/node from 20.2.5 to 20.3.0 in /node (#370)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.2.5 to 20.3.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.2.5&new-version=20.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-11 21:05:07 -05:00
dependabot[bot]
b3b5e67abb chore(deps-dev): Bump typescript from 5.0.4 to 5.1.3 in /node (#365)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.0.4
to 5.1.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Microsoft/TypeScript/releases">typescript's
releases</a>.</em></p>
<blockquote>
<h2>TypeScript 5.1.3</h2>
<p>For release notes, check out the <a
href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-1/">release
announcement</a>.</p>
<p>For the complete list of fixed issues, check out the</p>
<ul>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.0%22+is%3Aclosed+">fixed
issues query for Typescript 5.1.0 (Beta)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.1%22+is%3Aclosed+">fixed
issues query for Typescript 5.1.1 (RC)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.3%22+is%3Aclosed+">fixed
issues query for Typescript 5.1.3 (Stable)</a>.</li>
</ul>
<p>Downloads are available on:</p>
<ul>
<li><a
href="https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild">NuGet
package</a></li>
</ul>
<h2>TypeScript 5.1 RC</h2>
<p>For release notes, check out the <a
href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-rc/">release
announcement</a>.</p>
<p>For the complete list of fixed issues, check out the</p>
<ul>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.0%22+is%3Aclosed+">fixed
issues query for Typescript 5.1.0 (Beta)</a>.</li>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=milestone%3A%22TypeScript+5.1.1%22+is%3Aclosed+">fixed
issues query for Typescript 5.1.1 (RC)</a>.</li>
</ul>
<p>Downloads are available on:</p>
<ul>
<li><a
href="https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild">NuGet
package</a></li>
</ul>
<h2>TypeScript 5.1 Beta</h2>
<p>For release notes, check out the <a
href="https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-beta/">release
announcement</a>.</p>
<p>For the complete list of fixed issues, check out the</p>
<ul>
<li><a
href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=is%3Aissue+milestone%3A%22TypeScript+5.1.0%22+is%3Aclosed+">fixed
issues query for Typescript 5.1.0 (Beta)</a>.</li>
</ul>
<p>Downloads are available on:</p>
<ul>
<li><a
href="https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild">NuGet
package</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7275ded359"><code>7275ded</code></a>
Bump version to 5.1.3 and update LKG.</li>
<li><a
href="1143a21f03"><code>1143a21</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54454">#54454</a>
(Use <code>replaceAll</code> instead of an inco...) into release-5.1
(#...</li>
<li><a
href="b7d523ecbb"><code>b7d523e</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54450">#54450</a>
(Resolve tslib re-exports before che...) into release-5.1 (#...</li>
<li><a
href="a360d9fb3a"><code>a360d9f</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54315">#54315</a>
(add baseline for linked editing) into release-5.1 (<a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54419">#54419</a>)</li>
<li><a
href="c8da9d59fe"><code>c8da9d5</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54358">#54358</a>
(Don't use text change's `createNewF...) into release-5.1 (#...</li>
<li><a
href="cede745ab3"><code>cede745</code></a>
Cherry-picks 544d432 into release-5.1.</li>
<li><a
href="a38e4f5749"><code>a38e4f5</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54169">#54169</a>
(Fix creation of composite union typ...) into release-5.1 (#...</li>
<li><a
href="898edb5381"><code>898edb5</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54208">#54208</a>
(Properly handle <code>typeof this.xxx</code> i...) into release-5.1
(#...</li>
<li><a
href="42e783930e"><code>42e7839</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54317">#54317</a>
(Resolve re-exports when looking for...) into release-5.1 (#...</li>
<li><a
href="ed924d0585"><code>ed924d0</code></a>
🤖 Pick PR <a
href="https://redirect.github.com/Microsoft/TypeScript/issues/54112">#54112</a>
(Fix <code>isGenericReducibleType</code> to all...) into release-5.1
(#...</li>
<li>Additional commits viewable in <a
href="https://github.com/Microsoft/TypeScript/compare/v5.0.4...v5.1.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typescript&package-manager=npm_and_yarn&previous-version=5.0.4&new-version=5.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-11 21:04:26 -05:00
dependabot[bot]
128b3173a8 chore(deps-dev): Bump typedoc from 0.24.7 to 0.24.8 in /node (#364)
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.24.7 to
0.24.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/TypeDoc/releases">typedoc's
releases</a>.</em></p>
<blockquote>
<h2>v0.24.8</h2>
<h3>Features</h3>
<ul>
<li>Added support for TypeScript 5.1, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2296">#2296</a>.</li>
<li>Added <code>navigation.fullTree</code> to control rendering the full
navigation tree on each page, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2287">#2287</a>.
This option will likely be replaced in 0.25 with dynamic loading of the
full tree.</li>
<li>TypeDoc's <code>--pretty</code> option now also controls whether
generated HTML contains line breaks, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2287">#2287</a>.</li>
<li>Optimized icon caching to reduce file size in generated HTML
documentation, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2287">#2287</a>.</li>
<li>Render property description of &quot;roughly top level&quot; object
types, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2276">#2276</a>.</li>
<li>Added <code>MarkdownEvent.INCLUDE</code> for plugins, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2284">#2284</a>.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>When rendering functions/methods, TypeDoc will now render the
comment summary above the parameters/return type,
and any other block tags in the order they are defined in the comment,
<a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2285">#2285</a>.</li>
<li>Comments are no longer removed from classes/interfaces containing
call signatures, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2290">#2290</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/krisztianb"><code>@​krisztianb</code></a></li>
<li><a href="https://github.com/WikiRik"><code>@​WikiRik</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md">typedoc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.24.8 (2023-06-04)</h2>
<h3>Features</h3>
<ul>
<li>Added support for TypeScript 5.1, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2296">#2296</a>.</li>
<li>Added <code>navigation.fullTree</code> to control rendering the full
navigation tree on each page, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2287">#2287</a>.
This option will likely be replaced in 0.25 with dynamic loading of the
full tree.</li>
<li>TypeDoc's <code>--pretty</code> option now also controls whether
generated HTML contains line breaks, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2287">#2287</a>.</li>
<li>Optimized icon caching to reduce file size in generated HTML
documentation, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2287">#2287</a>.</li>
<li>Render property description of &quot;roughly top level&quot; object
types, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2276">#2276</a>.</li>
<li>Added <code>MarkdownEvent.INCLUDE</code> for plugins, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2284">#2284</a>.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>When rendering functions/methods, TypeDoc will now render the
comment summary above the parameters/return type,
and any other block tags in the order they are defined in the comment,
<a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2285">#2285</a>.</li>
<li>Comments are no longer removed from classes/interfaces containing
call signatures, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2290">#2290</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/krisztianb"><code>@​krisztianb</code></a></li>
<li><a href="https://github.com/WikiRik"><code>@​WikiRik</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c1c87c6fda"><code>c1c87c6</code></a>
Update changelog for release</li>
<li><a
href="0b2a8ea78a"><code>0b2a8ea</code></a>
Bump version to 0.24.8</li>
<li><a
href="60c4d533e5"><code>60c4d53</code></a>
Add navigation.fullTree option</li>
<li><a
href="82016b82b5"><code>82016b8</code></a>
Update changelog</li>
<li><a
href="4ad6a31776"><code>4ad6a31</code></a>
Add test for unrelated getter/setter types</li>
<li><a
href="d05a49b088"><code>d05a49b</code></a>
Added support for TypeScript 5.1 (<a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/2300">#2300</a>)</li>
<li><a
href="6d92e84b8a"><code>6d92e84</code></a>
Render objects one level deep</li>
<li><a
href="c9dee384b0"><code>c9dee38</code></a>
Update comment rendering for functions</li>
<li><a
href="2624c288fa"><code>2624c28</code></a>
Fix call signature handling on classes/interfaces</li>
<li><a
href="5b9ead63d3"><code>5b9ead6</code></a>
Update changelog</li>
<li>Additional commits viewable in <a
href="https://github.com/TypeStrong/TypeDoc/compare/v0.24.7...v0.24.8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typedoc&package-manager=npm_and_yarn&previous-version=0.24.7&new-version=0.24.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-11 21:04:07 -05:00
dependabot[bot]
ef0b6b46ac chore(deps-dev): Bump @types/jest from 29.5.1 to 29.5.2 in /node (#363)
Bumps
[@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest)
from 29.5.1 to 29.5.2.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/jest&package-manager=npm_and_yarn&previous-version=29.5.1&new-version=29.5.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-11 21:03:47 -05:00
zach
2e5f5ef716 fix(rust): fix lifetime of data returned from Plugin::call (#369) 2023-06-09 12:07:14 -07:00
zach
360df45e1a fix: require modules to have exported, bounded memory when manifest memory.max_pages field is set (#356)
- Requires modules compiled to run with manifests that set `max_memory`
to have an exported memory with lower and upper bounds
- Includes the size of memory exported from modules when calculating
available memory for plugins

## How to compile a module with bounded memory 

You will need to pass `--max-memory=$NUM_BYTES` to wasm-ld. `$NUM_BYTES`
must be a multiple of the page size. Here are some examples for
supported PDK languages:

**C** 
Pass `-Wl,--max-memory=65536` to your C compiler

**Rust**: 
In a `.cargo/config` file:
```toml
[target.wasm32-unknown-unknown]
rustflags = ["-Clink-args=--max-memory=65536"]
 ```
**Haskell**
Add the following to the cabal file entry for your `cabal.project` file:

```
package myproject
  ghc-options:
    -optl -Wl,--max-memory=65536
```
**AssemblyScript**
Pass `--maximumMemory 65536` to the assemblyscropt compiler

**TinyGo**:
Create a `target.json` file:
```json
{
    "inherits": [ "wasm" ],
    "ldflags": [
        "--max-memory=65536",
    ]
}
```
and build using `tinygo -target ./target.json`
2023-06-01 09:37:42 -07:00
dependabot[bot]
3bdf4ef0d0 chore(deps-dev): Bump @types/node from 20.2.3 to 20.2.5 in /node (#358)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.2.3 to 20.2.5.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.2.3&new-version=20.2.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-31 11:59:31 -05:00
dependabot[bot]
0517aca413 chore(deps-dev): Bump @types/node from 20.1.4 to 20.2.3 in /node (#353)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 20.1.4 to 20.2.3.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=20.1.4&new-version=20.2.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-23 21:34:11 -05:00
zach
a6807a44c9 fix(ocaml): update dune-project file (#355)
See
https://github.com/ocaml/opam-repository/pull/23806#discussion_r1201772532
2023-05-23 09:35:32 -07:00
zach
dc6f99d924 cleanup(ocaml): add bounds on extism-manifest dependency (#354) 2023-05-23 09:31:16 -07:00
Benjamin Eckel
62267e874a chore(java): release Java SDK (#352) 2023-05-19 16:29:12 -05:00
Benjamin Eckel
ab0a7c1650 chore(elixir): Bump to 0.4.0 (#350) 2023-05-19 16:01:16 -05:00
Benjamin Eckel
12820aecff fix: ignore already published manifest (#351) 2023-05-19 15:35:35 -05:00
Benjamin Eckel
1db4528490 chore: Bump SDK versions for 0.4.0 release (#349)
Co-authored-by: zach <zach@dylibso.com>
2023-05-19 15:22:58 -05:00
71 changed files with 2648 additions and 1946 deletions

View File

@@ -10,13 +10,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install extism shared library
shell: bash
run: |
mkdir -p /home/runner/.local/bin/
export PATH="/home/runner/.local/bin/:$PATH"
curl https://raw.githubusercontent.com/extism/cli/main/install.sh | sh
extism --sudo --prefix /usr/local install
- name: Setup Elixir Host SDK
uses: erlef/setup-beam@v1
with:

View File

@@ -19,16 +19,22 @@ jobs:
override: true
target: ${{ matrix.target }}
- name: Release Rust Host SDK
- name: Release Rust Manifest Crate
if: always()
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_API_TOKEN }}
run: |
# order of crate publication matter: manifest, runtime, rust
cargo publish --manifest-path manifest/Cargo.toml
# allow for crates.io to update so dependant crates can locate extism-manifest
sleep 5
- name: Release Rust Host SDK
if: always()
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_API_TOKEN }}
run: |
cargo publish --manifest-path runtime/Cargo.toml --no-verify
cargo publish --manifest-path rust/Cargo.toml

View File

@@ -5,3 +5,4 @@ members = [
"rust",
"libextism",
]
exclude = ["kernel"]

View File

@@ -21,6 +21,10 @@ endif
build:
cargo build --release $(FEATURE_FLAGS) --manifest-path libextism/Cargo.toml
.PHONY: kernel
kernel:
cd kernel && bash build.sh
lint:
cargo clippy --release --no-deps --manifest-path runtime/Cargo.toml

View File

@@ -1,12 +1,12 @@
{
"name": "@extism/runtime-browser",
"version": "0.2.7",
"version": "0.3.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@extism/runtime-browser",
"version": "0.2.7",
"version": "0.3.0",
"license": "BSD-3-Clause",
"dependencies": {
"@bjorn3/browser_wasi_shim": "^0.2.7"
@@ -7618,9 +7618,9 @@
}
},
"node_modules/tough-cookie": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
"integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"dev": true,
"dependencies": {
"psl": "^1.1.33",
@@ -8108,9 +8108,9 @@
}
},
"node_modules/word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -13986,9 +13986,9 @@
}
},
"tough-cookie": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
"integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"dev": true,
"requires": {
"psl": "^1.1.33",
@@ -14334,9 +14334,9 @@
}
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
"dev": true
},
"wrap-ansi": {

View File

@@ -1,24 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<PropertyGroup>
<PackageId>Extism.runtime.win-x64</PackageId>
<Version>0.6.0</Version>
<Authors>Extism Contributors</Authors>
<Description>Internal implementation package for Extism to work on Windows x64</Description>
<Tags>extism, wasm, plugin</Tags>
<PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression>
</PropertyGroup>
<PropertyGroup>
<PackageId>Extism.runtime.win-x64</PackageId>
<Version>0.7.0</Version>
<Authors>Extism Contributors</Authors>
<Description>Internal implementation package for Extism to work on Windows x64</Description>
<Tags>extism, wasm, plugin</Tags>
<PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression>
</PropertyGroup>
<ItemGroup>
<Content Include="runtimes/win-x64.dll"
CopyToOutputDirectory="Always"
Pack="true"
PackagePath="runtimes\win-x64\native\extism.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="runtimes/win-x64.dll"
CopyToOutputDirectory="Always"
Pack="true"
PackagePath="runtimes\win-x64\native\extism.dll" />
</ItemGroup>
</Project>

View File

@@ -1,28 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>10</LangVersion>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>10</LangVersion>
</PropertyGroup>
<PropertyGroup>
<PackageId>Extism.Sdk</PackageId>
<Version>0.5.0</Version>
<Authors>Extism Contributors</Authors>
<Description>Extism SDK that allows hosting Extism plugins in .NET apps.</Description>
<Tags>extism, wasm, plugin</Tags>
<PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<PropertyGroup>
<PackageId>Extism.Sdk</PackageId>
<Version>0.7.0</Version>
<Authors>Extism Contributors</Authors>
<Description>Extism SDK that allows hosting Extism plugins in .NET apps.</Description>
<Tags>extism, wasm, plugin</Tags>
<PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\"/>
</ItemGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>
</Project>

View File

@@ -65,7 +65,7 @@ namespace Extism.Sdk
NativeHandle = LibExtism.extism_function_new(functionName, inputs, inputTypes.Length, outputs, outputTypes.Length, CallbackImpl, userData, IntPtr.Zero);
}
if (!string.IsNullOrEmpty(functionName))
if (!string.IsNullOrEmpty(@namespace))
{
LibExtism.extism_function_set_namespace(NativeHandle, @namespace);
}

View File

@@ -26,7 +26,7 @@
(ctypes-foreign (>= 0.18.0))
(bigstringaf (>= 0.9.0))
(ppx_yojson_conv (>= v0.15.0))
extism-manifest
(extism-manifest (= :version))
(ppx_inline_test (>= v0.15.0))
(cmdliner (>= 1.1.1))
)

View File

@@ -4,7 +4,7 @@ defmodule Extism.MixProject do
def project do
[
app: :extism,
version: "0.3.2",
version: "0.5.1",
elixir: "~> 1.12",
start_permanent: Mix.env() == :prod,
deps: deps(),
@@ -23,7 +23,7 @@ defmodule Extism.MixProject do
defp deps do
[
{:rustler, "~> 0.28.0"},
{:rustler, "~> 0.29.1"},
{:json, "~> 1.4"},
{:ex_doc, "~> 0.21", only: :dev, runtime: false}
]

View File

@@ -1,12 +1,12 @@
%{
"earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"},
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
"earmark_parser": {:hex, :earmark_parser, "1.4.33", "3c3fd9673bb5dcc9edc28dd90f50c87ce506d1f71b70e3de69aa8154bc695d44", [:mix], [], "hexpm", "2d526833729b59b9fdb85785078697c72ac5e5066350663e5be6a1182da61b8f"},
"ex_doc": {:hex, :ex_doc, "0.30.5", "aa6da96a5c23389d7dc7c381eba862710e108cee9cfdc629b7ec021313900e9e", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "88a1e115dcb91cefeef7e22df4a6ebbe4634fbf98b38adcbc25c9607d6d9d8e6"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"json": {:hex, :json, "1.4.1", "8648f04a9439765ad449bc56a3ff7d8b11dd44ff08ffcdefc4329f7c93843dfa", [:mix], [], "hexpm", "9abf218dbe4ea4fcb875e087d5f904ef263d012ee5ed21d46e9dbca63f053d16"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"rustler": {:hex, :rustler, "0.28.0", "b8e2c43013e12dd06f61dcf87033d2e2c8245feddb121b82179c923be31ad319", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "99f811f58c993f0343851adb0af589a99cfd3dc20f2efb8ef08d1a8447980b98"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"rustler": {:hex, :rustler, "0.29.1", "880f20ae3027bd7945def6cea767f5257bc926f33ff50c0d5d5a5315883c084d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "109497d701861bfcd26eb8f5801fe327a8eef304f56a5b63ef61151ff44ac9b6"},
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
}

View File

@@ -13,6 +13,6 @@ crate-type = ["cdylib"]
[workspace]
[dependencies]
rustler = "0.28.0"
extism = "0.3.0"
rustler = "0.29.1"
extism = "0.5.2"
log = "0.4"

View File

@@ -173,8 +173,9 @@ func (ctx *Context) Free() {
// Plugin is used to call WASM functions
type Plugin struct {
ctx *Context
id int32
ctx *Context
id int32
functions []Function
}
type WasmData struct {
@@ -272,7 +273,7 @@ func register(ctx *Context, data []byte, functions []Function, wasi bool) (Plugi
)
}
return Plugin{id: int32(plugin), ctx: ctx}, nil
return Plugin{id: int32(plugin), ctx: ctx, functions: functions}, nil
}
func update(ctx *Context, plugin int32, data []byte, functions []Function, wasi bool) error {
@@ -361,7 +362,7 @@ func (p *Plugin) Update(module io.Reader, functions []Function, wasi bool) error
if err != nil {
return err
}
p.functions = functions
return update(p.ctx, p.id, wasm, functions, wasi)
}
@@ -372,6 +373,7 @@ func (p *Plugin) UpdateManifest(manifest Manifest, functions []Function, wasi bo
return err
}
p.functions = functions
return update(p.ctx, p.id, data, functions, wasi)
}

View File

@@ -16,7 +16,7 @@ depends: [
"ctypes-foreign" {>= "0.18.0"}
"bigstringaf" {>= "0.9.0"}
"ppx_yojson_conv" {>= "v0.15.0"}
"extism-manifest"
"extism-manifest" {= version}
"ppx_inline_test" {>= "v0.15.0"}
"cmdliner" {>= "1.1.1"}
"odoc" {with-doc}

View File

@@ -1,15 +1,24 @@
module Main where
import Extism
import Extism.CurrentPlugin
import Extism.Manifest(manifest, wasmFile)
unwrap (Right x) = x
unwrap (Left (ExtismError msg)) = do
error msg
hello plugin params msg = do
putStrLn "Hello from Haskell!"
putStrLn msg
offs <- allocBytes plugin (toByteString "{\"count\": 999}")
return [toI64 offs]
main = do
let m = manifest [wasmFile "../wasm/code.wasm"]
plugin <- unwrap <$> Extism.createPluginFromManifest m False
res <- unwrap <$> Extism.call plugin "count_vowels" (Extism.toByteString "this is a test")
putStrLn (Extism.fromByteString res)
Extism.free plugin
setLogFile "stdout" Error
let m = manifest [wasmFile "../wasm/code-functions.wasm"]
f <- hostFunction "hello_world" [I64] [I64] hello "Hello, again"
plugin <- unwrap <$> createPluginFromManifest m [f] True
res <- unwrap <$> call plugin "count_vowels" (toByteString "this is a test")
putStrLn (fromByteString res)
free plugin

View File

@@ -1,6 +1,6 @@
cabal-version: 3.0
name: extism
version: 0.2.0
version: 0.5.0
license: BSD-3-Clause
maintainer: oss@extism.org
author: Extism authors
@@ -8,10 +8,10 @@ bug-reports: https://github.com/extism/extism
synopsis: Extism bindings
description: Bindings to Extism, the universal plugin system
category: Plugins, WebAssembly
extra-source-files: CHANGELOG.md
extra-doc-files: CHANGELOG.md
library
exposed-modules: Extism
exposed-modules: Extism Extism.CurrentPlugin
reexported-modules: Extism.Manifest
hs-source-dirs: src
other-modules: Extism.Bindings
@@ -19,10 +19,10 @@ library
extra-libraries: extism
extra-lib-dirs: /usr/local/lib
build-depends:
base >= 4.16.1 && < 4.19.0,
bytestring >= 0.11.3 && < 0.12,
json >= 0.10 && < 0.11,
extism-manifest >= 0.0.0 && < 0.3.0
base >= 4.16.1 && < 5,
bytestring >= 0.11.3 && <= 0.12,
json >= 0.10 && <= 0.11,
extism-manifest >= 0.0.0 && < 0.4.0
test-suite extism-example
type: exitcode-stdio-1.0

View File

@@ -16,8 +16,8 @@ isNull JSNull = True
isNull _ = False
filterNulls obj = [(a, b) | (a, b) <- obj, not (isNull b)]
object x = makeObj $ filterNulls x
objectWithNulls x = makeObj x
nonNull x = NotNull x
objectWithNulls = makeObj
nonNull = NotNull
null' = Null
(.=) a b = (a, showJSON b)
toNullable (Just x) = NotNull x
@@ -40,7 +40,7 @@ find :: JSON a => String -> JSValue -> Nullable a
find k obj = obj .? k
update :: JSON a => String -> a -> JSValue -> JSValue
update k v (JSObject obj) = object $ (fromJSObject obj) ++ [k .= v]
update k v (JSObject obj) = object $ fromJSObject obj ++ [k .= v]
instance JSON a => JSON (Nullable a) where
showJSON (NotNull x) = showJSON x

View File

@@ -1,6 +1,6 @@
cabal-version: 3.0
name: extism-manifest
version: 0.2.0
version: 0.3.0
license: BSD-3-Clause
maintainer: oss@extism.org
author: Extism authors
@@ -8,14 +8,14 @@ bug-reports: https://github.com/extism/extism
synopsis: Extism manifest bindings
description: Bindings to Extism WebAssembly manifest
category: Plugins, WebAssembly
extra-source-files: CHANGELOG.md
extra-doc-files: CHANGELOG.md
library
exposed-modules: Extism.Manifest Extism.JSON
hs-source-dirs: .
default-language: Haskell2010
build-depends:
base >= 4.16.1 && < 4.19.0,
bytestring >= 0.11.3 && < 0.12,
json >= 0.10 && < 0.11,
base >= 4.16.1 && < 5,
bytestring >= 0.11.3 && <= 0.12,
json >= 0.10 && <= 0.11,
base64-bytestring >= 1.2.1 && < 1.3,

View File

@@ -1,10 +1,21 @@
module Extism (module Extism, module Extism.Manifest) where
module Extism (
module Extism,
module Extism.Manifest,
ValType(..),
Val(..)
) where
import Data.Int
import Data.Word
import Control.Monad (void)
import Foreign.ForeignPtr
import Foreign.C.String
import Foreign.Ptr
import Foreign.Marshal.Array
import Foreign.Storable
import Foreign.StablePtr
import Foreign.Concurrent
import Foreign.Marshal.Utils (copyBytes, moveBytes)
import Data.ByteString as B
import Data.ByteString.Internal (c2w, w2c)
import Data.ByteString.Unsafe (unsafeUseAsCString)
@@ -16,10 +27,17 @@ import Extism.Bindings
-- | Context for managing plugins
newtype Context = Context (ForeignPtr ExtismContext)
-- | Plugins can be used to call WASM function
data Plugin = Plugin Context Int32
-- | Host function
data Function = Function (ForeignPtr ExtismFunction) (StablePtr ())
data CancelHandle = CancelHandle (Ptr ExtismCancelHandle)
-- | Plugins can be used to call WASM function
data Plugin = Plugin Context Int32 [Function]
-- | Cancellation handle for Plugins
newtype CancelHandle = CancelHandle (Ptr ExtismCancelHandle)
-- | Access the plugin that is currently executing from inside a host function
type CurrentPlugin = Ptr ExtismCurrentPlugin
-- | Log level
data LogLevel = Error | Warn | Info | Debug | Trace deriving (Show)
@@ -53,80 +71,94 @@ reset (Context ctx) =
newContext :: IO Context
newContext = do
ptr <- extism_context_new
fptr <- newForeignPtr extism_context_free ptr
fptr <- Foreign.ForeignPtr.newForeignPtr extism_context_free ptr
return (Context fptr)
-- | Execute a function with a new 'Context' that is destroyed when it returns
withContext :: (Context -> IO a) -> IO a
withContext f = do
ctx <- newContext
f ctx
-- | Execute a function with the provided 'Plugin' as a parameter, then frees the 'Plugin'
-- | before returning the result.
withPlugin :: (Plugin -> IO a) -> Plugin -> IO a
withPlugin f plugin = do
res <- f plugin
free plugin
return res
-- | Create a 'Plugin' from a WASM module, `useWasi` determines if WASI should
-- | be linked
plugin :: Context -> B.ByteString -> Bool -> IO (Result Plugin)
plugin c wasm useWasi =
plugin :: Context -> B.ByteString -> [Function] -> Bool -> IO (Result Plugin)
plugin c wasm functions useWasi =
let nfunctions = fromIntegral (Prelude.length functions) in
let length = fromIntegral (B.length wasm) in
let wasi = fromInteger (if useWasi then 1 else 0) in
let Context ctx = c in
do
funcs <- Prelude.mapM (\(Function ptr _) -> withForeignPtr ptr (\x -> do return x)) functions
withForeignPtr ctx (\ctx -> do
p <- unsafeUseAsCString wasm (\s ->
extism_plugin_new ctx (castPtr s) length nullPtr 0 wasi )
withArray funcs (\funcs ->
extism_plugin_new ctx (castPtr s) length funcs nfunctions wasi ))
if p < 0 then do
err <- extism_error ctx (-1)
e <- peekCString err
return $ Left (ExtismError e)
else
return $ Right (Plugin c p))
return $ Right (Plugin c p functions))
-- | Create a 'Plugin' with its own 'Context'
createPlugin :: B.ByteString -> Bool -> IO (Result Plugin)
createPlugin c useWasi = do
createPlugin :: B.ByteString -> [Function] -> Bool -> IO (Result Plugin)
createPlugin c functions useWasi = do
ctx <- newContext
plugin ctx c useWasi
plugin ctx c functions useWasi
-- | Create a 'Plugin' from a 'Manifest'
pluginFromManifest :: Context -> Manifest -> Bool -> IO (Result Plugin)
pluginFromManifest ctx manifest useWasi =
pluginFromManifest :: Context -> Manifest -> [Function] -> Bool -> IO (Result Plugin)
pluginFromManifest ctx manifest functions useWasi =
let wasm = toByteString $ toString manifest in
plugin ctx wasm useWasi
plugin ctx wasm functions useWasi
-- | Create a 'Plugin' with its own 'Context' from a 'Manifest'
createPluginFromManifest :: Manifest -> Bool -> IO (Result Plugin)
createPluginFromManifest manifest useWasi = do
createPluginFromManifest :: Manifest -> [Function] -> Bool -> IO (Result Plugin)
createPluginFromManifest manifest functions useWasi = do
ctx <- newContext
pluginFromManifest ctx manifest useWasi
pluginFromManifest ctx manifest functions useWasi
-- | Update a 'Plugin' with a new WASM module
update :: Plugin -> B.ByteString -> Bool -> IO (Result ())
update (Plugin (Context ctx) id) wasm useWasi =
update :: Plugin -> B.ByteString -> [Function] -> Bool -> IO (Result Plugin)
update (Plugin (Context ctx) id _) wasm functions useWasi =
let nfunctions = fromIntegral (Prelude.length functions) in
let length = fromIntegral (B.length wasm) in
let wasi = fromInteger (if useWasi then 1 else 0) in
do
withForeignPtr ctx (\ctx -> do
funcs <- Prelude.mapM (\(Function ptr _ ) -> withForeignPtr ptr (\x -> do return x)) functions
withForeignPtr ctx (\ctx' -> do
b <- unsafeUseAsCString wasm (\s ->
extism_plugin_update ctx id (castPtr s) length nullPtr 0 wasi)
withArray funcs (\funcs ->
extism_plugin_update ctx' id (castPtr s) length funcs nfunctions wasi))
if b <= 0 then do
err <- extism_error ctx (-1)
err <- extism_error ctx' (-1)
e <- peekCString err
return $ Left (ExtismError e)
else
return (Right ()))
return (Right (Plugin (Context ctx) id functions)))
-- | Update a 'Plugin' with a new 'Manifest'
updateManifest :: Plugin -> Manifest -> Bool -> IO (Result ())
updateManifest plugin manifest useWasi =
updateManifest :: Plugin -> Manifest -> [Function] -> Bool -> IO (Result Plugin)
updateManifest plugin manifest functions useWasi =
let wasm = toByteString $ toString manifest in
update plugin wasm useWasi
update plugin wasm functions useWasi
-- | Check if a 'Plugin' is valid
isValid :: Plugin -> Bool
isValid (Plugin _ p) = p >= 0
isValid (Plugin _ p _) = p >= 0
-- | Set configuration values for a plugin
setConfig :: Plugin -> [(String, Maybe String)] -> IO Bool
setConfig (Plugin (Context ctx) plugin) x =
setConfig (Plugin (Context ctx) plugin _) x =
if plugin < 0
then return False
else
@@ -155,14 +187,14 @@ setLogFile filename level =
-- | Check if a function exists in the given plugin
functionExists :: Plugin -> String -> IO Bool
functionExists (Plugin (Context ctx) plugin) name = do
functionExists (Plugin (Context ctx) plugin _) name = do
withForeignPtr ctx (\ctx -> do
b <- withCString name (extism_plugin_function_exists ctx plugin)
if b == 1 then return True else return False)
--- | Call a function provided by the given plugin
call :: Plugin -> String -> B.ByteString -> IO (Result B.ByteString)
call (Plugin (Context ctx) plugin) name input =
call (Plugin (Context ctx) plugin _) name input =
let length = fromIntegral (B.length input) in
do
withForeignPtr ctx (\ctx -> do
@@ -184,15 +216,73 @@ call (Plugin (Context ctx) plugin) name input =
-- | Free a 'Plugin', this will automatically be called for every plugin
-- | associated with a 'Context' when that 'Context' is freed
free :: Plugin -> IO ()
free (Plugin (Context ctx) plugin) =
free (Plugin (Context ctx) plugin _) =
withForeignPtr ctx (`extism_plugin_free` plugin)
-- | Create a new 'CancelHandle' that can be used to cancel a running plugin
-- | from another thread.
cancelHandle :: Plugin -> IO CancelHandle
cancelHandle (Plugin (Context ctx) plugin) = do
handle <- withForeignPtr ctx (\ctx -> extism_plugin_cancel_handle ctx plugin)
cancelHandle (Plugin (Context ctx) plugin _) = do
handle <- withForeignPtr ctx (`extism_plugin_cancel_handle` plugin)
return (CancelHandle handle)
-- | Cancel a running plugin using a 'CancelHandle'
cancel :: CancelHandle -> IO Bool
cancel (CancelHandle handle) =
cancel (CancelHandle handle) =
extism_plugin_cancel handle
-- | Create a new 'Function' that can be called from a 'Plugin'
hostFunction :: String -> [ValType] -> [ValType] -> (CurrentPlugin -> [Val] -> a -> IO [Val]) -> a -> IO Function
hostFunction name params results f v =
let nparams = fromIntegral $ Prelude.length params in
let nresults = fromIntegral $ Prelude.length results in
do
cb <- callbackWrap (callback f :: CCallback)
free <- freePtrWrap freePtr
userData <- newStablePtr (v, free, cb)
let userDataPtr = castStablePtrToPtr userData
x <- withCString name (\name -> do
withArray params (\params ->
withArray results (\results -> do
extism_function_new name params nparams results nresults cb userDataPtr free)))
let freeFn = extism_function_free x
fptr <- Foreign.Concurrent.newForeignPtr x freeFn
return $ Function fptr (castPtrToStablePtr userDataPtr)
-- | Create a new I32 'Val'
toI32 :: Integral a => a -> Val
toI32 x = ValI32 (fromIntegral x)
-- | Create a new I64 'Val'
toI64 :: Integral a => a -> Val
toI64 x = ValI64 (fromIntegral x)
-- | Create a new F32 'Val'
toF32 :: Float -> Val
toF32 = ValF32
-- | Create a new F64 'Val'
toF64 :: Double -> Val
toF64 = ValF64
-- | Get I32 'Val'
fromI32 :: Integral a => Val -> Maybe a
fromI32 (ValI32 x) = Just (fromIntegral x)
fromI32 _ = Nothing
-- | Get I64 'Val'
fromI64 :: Integral a => Val -> Maybe a
fromI64 (ValI64 x) = Just (fromIntegral x)
fromI64 _ = Nothing
-- | Get F32 'Val'
fromF32 :: Val -> Maybe Float
fromF32 (ValF32 x) = Just x
fromF32 _ = Nothing
-- | Get F64 'Val'
fromF64 :: Val -> Maybe Double
fromF64 (ValF64 x) = Just x
fromF64 _ = Nothing

View File

@@ -7,10 +7,77 @@ import Foreign.Ptr
import Foreign.C.String
import Data.Int
import Data.Word
import Foreign.Storable
import Foreign.Marshal.Array
import Foreign.StablePtr
type FreeCallback = Ptr () -> IO ()
newtype ExtismContext = ExtismContext () deriving Show
newtype ExtismFunction = ExtismFunction () deriving Show
newtype ExtismCancelHandle = ExtismCancelHandle () deriving Show
newtype ExtismCurrentPlugin = ExtismCurrentPlugin () deriving Show
data ValType = I32 | I64 | F32 | F64 | V128 | FuncRef | ExternRef deriving (Show, Eq)
data Val = ValI32 Int32 | ValI64 Int64 | ValF32 Float | ValF64 Double deriving (Show, Eq)
typeOfVal (ValI32 _) = I32
typeOfVal (ValI64 _) = I64
typeOfVal (ValF32 _) = F32
typeOfVal (ValF64 _) = F64
type CCallback = Ptr ExtismCurrentPlugin -> Ptr Val -> Word64 -> Ptr Val -> Word64 -> Ptr () -> IO ()
_32Bit = sizeOf (undefined :: Int) == 4
instance Storable Val where
sizeOf _ =
if _32Bit then 12 else 16
alignment _ = 1
peek ptr = do
let offs = if _32Bit then 4 else 8
t <- valTypeOfInt <$> peekByteOff ptr 0
case t of
I32 -> ValI32 <$> peekByteOff ptr offs
I64 -> ValI64 <$> peekByteOff ptr offs
F32 -> ValF32 <$> peekByteOff ptr offs
F64 -> ValF64 <$> peekByteOff ptr offs
poke ptr x = do
let offs = if _32Bit then 4 else 8
pokeByteOff ptr 0 (typeOfVal x)
case x of
ValI32 x -> pokeByteOff ptr offs x
ValI64 x -> pokeByteOff ptr offs x
ValF32 x -> pokeByteOff ptr offs x
ValF64 x -> pokeByteOff ptr offs x
intOfValType :: ValType -> CInt
intOfValType I32 = 0
intOfValType I64 = 1
intOfValType F32 = 2
intOfValType F64 = 3
intOfValType V128 = 4
intOfValType FuncRef = 5
intOfValType ExternRef = 6
valTypeOfInt :: CInt -> ValType
valTypeOfInt 0 = I32
valTypeOfInt 1 = I64
valTypeOfInt 2 = F32
valTypeOfInt 3 = F64
valTypeOfInt 4 = V128
valTypeOfInt 5 = FuncRef
valTypeOfInt 6 = ExternRef
valTypeOfInt _ = error "Invalid ValType"
instance Storable ValType where
sizeOf _ = 4
alignment _ = 1
peek ptr = do
x <- peekByteOff ptr 0
return $ valTypeOfInt (x :: CInt)
poke ptr x = do
pokeByteOff ptr 0 (intOfValType x)
foreign import ccall safe "extism.h extism_context_new" extism_context_new :: IO (Ptr ExtismContext)
foreign import ccall safe "extism.h &extism_context_free" extism_context_free :: FunPtr (Ptr ExtismContext -> IO ())
@@ -28,3 +95,28 @@ foreign import ccall safe "extism.h extism_context_reset" extism_context_reset :
foreign import ccall safe "extism.h extism_version" extism_version :: IO CString
foreign import ccall safe "extism.h extism_plugin_cancel_handle" extism_plugin_cancel_handle :: Ptr ExtismContext -> Int32 -> IO (Ptr ExtismCancelHandle)
foreign import ccall safe "extism.h extism_plugin_cancel" extism_plugin_cancel :: Ptr ExtismCancelHandle -> IO Bool
foreign import ccall safe "extism.h extism_function_new" extism_function_new :: CString -> Ptr ValType -> Word64 -> Ptr ValType -> Word64 -> FunPtr CCallback -> Ptr () -> FunPtr FreeCallback -> IO (Ptr ExtismFunction)
foreign import ccall safe "extism.h extism_function_free" extism_function_free :: Ptr ExtismFunction -> IO ()
foreign import ccall safe "extism.h extism_current_plugin_memory" extism_current_plugin_memory :: Ptr ExtismCurrentPlugin -> IO (Ptr Word8)
foreign import ccall safe "extism.h extism_current_plugin_memory_alloc" extism_current_plugin_memory_alloc :: Ptr ExtismCurrentPlugin -> Word64 -> IO Word64
foreign import ccall safe "extism.h extism_current_plugin_memory_length" extism_current_plugin_memory_length :: Ptr ExtismCurrentPlugin -> Word64 -> IO Word64
foreign import ccall safe "extism.h extism_current_plugin_memory_free" extism_current_plugin_memory_free :: Ptr ExtismCurrentPlugin -> Word64 -> IO ()
freePtr ptr = do
let s = castPtrToStablePtr ptr
(a, b, c) <- deRefStablePtr s
freeHaskellFunPtr b
freeHaskellFunPtr c
freeStablePtr s
foreign import ccall "wrapper" freePtrWrap :: FreeCallback -> IO (FunPtr FreeCallback)
foreign import ccall "wrapper" callbackWrap :: CCallback -> IO (FunPtr CCallback)
callback :: (Ptr ExtismCurrentPlugin -> [Val] -> a -> IO [Val]) -> (Ptr ExtismCurrentPlugin -> Ptr Val -> Word64 -> Ptr Val -> Word64 -> Ptr () -> IO ())
callback f plugin params nparams results nresults ptr = do
p <- peekArray (fromIntegral nparams) params
(userData, _, _) <- deRefStablePtr (castPtrToStablePtr ptr)
res <- f plugin p userData
pokeArray results res

View File

@@ -0,0 +1,48 @@
module Extism.CurrentPlugin where
import Extism
import Extism.Bindings
import Data.Word
import Data.ByteString as B
import Foreign.Ptr
import Foreign.Marshal.Array
-- | Allocate a new handle of the given size
memoryAlloc :: CurrentPlugin -> Word64 -> IO Word64
memoryAlloc = extism_current_plugin_memory_alloc
-- | Get the length of a handle, returns 0 if the handle is invalid
memoryLength :: CurrentPlugin -> Word64 -> IO Word64
memoryLength = extism_current_plugin_memory_length
-- | Free allocated memory
memoryFree :: CurrentPlugin -> Word64 -> IO ()
memoryFree = extism_current_plugin_memory_free
-- | Access a pointer to the entire memory region
memory :: CurrentPlugin -> IO (Ptr Word8)
memory = extism_current_plugin_memory
-- | Access a pointer the a specific offset in memory
memoryOffset :: CurrentPlugin -> Word64 -> IO (Ptr Word8)
memoryOffset plugin offs = do
x <- extism_current_plugin_memory plugin
return $ plusPtr x (fromIntegral offs)
-- | Access the data associated with a handle as a 'ByteString'
memoryBytes :: CurrentPlugin -> Word64 -> IO B.ByteString
memoryBytes plugin offs = do
ptr <- memoryOffset plugin offs
len <- memoryLength plugin offs
arr <- peekArray (fromIntegral len) ptr
return $ B.pack arr
-- | Allocate memory and copy an existing 'ByteString' into it
allocBytes :: CurrentPlugin -> B.ByteString -> IO Word64
allocBytes plugin s = do
let length = B.length s
offs <- memoryAlloc plugin (fromIntegral length)
ptr <- memoryOffset plugin offs
pokeArray ptr (B.unpack s)
return offs

View File

@@ -1,6 +1,7 @@
import Test.HUnit
import Extism
import Extism.Manifest
import Extism.CurrentPlugin
unwrap (Right x) = return x
@@ -8,12 +9,13 @@ unwrap (Left (ExtismError msg)) =
assertFailure msg
defaultManifest = manifest [wasmFile "../../wasm/code.wasm"]
hostFunctionManifest = manifest [wasmFile "../../wasm/code-functions.wasm"]
initPlugin :: Maybe Context -> IO Plugin
initPlugin Nothing =
Extism.createPluginFromManifest defaultManifest False >>= unwrap
Extism.createPluginFromManifest defaultManifest [] False >>= unwrap
initPlugin (Just ctx) =
Extism.pluginFromManifest ctx defaultManifest False >>= unwrap
Extism.pluginFromManifest ctx defaultManifest [] False >>= unwrap
pluginFunctionExists = do
p <- initPlugin Nothing
@@ -30,6 +32,17 @@ pluginCall = do
p <- initPlugin Nothing
checkCallResult p
hello plugin params () = do
putStrLn "Hello from Haskell!"
offs <- allocBytes plugin (toByteString "{\"count\": 999}")
return [toI64 offs]
pluginCallHostFunction = do
p <- Extism.createPluginFromManifest hostFunctionManifest [] False >>= unwrap
res <- call p "count_vowels" (toByteString "this is a test") >>= unwrap
assertEqual "count vowels output" "{\"count\": 999}" (fromByteString res)
pluginMultiple = do
withContext(\ctx -> do
p <- initPlugin (Just ctx)
@@ -42,7 +55,7 @@ pluginMultiple = do
pluginUpdate = do
withContext (\ctx -> do
p <- initPlugin (Just ctx)
updateManifest p defaultManifest True >>= unwrap
updateManifest p defaultManifest [] True >>= unwrap
checkCallResult p)
pluginConfig = do
@@ -62,6 +75,7 @@ main = do
[
t "Plugin.FunctionExists" pluginFunctionExists
, t "Plugin.Call" pluginCall
, t "Plugin.CallHostFunction" pluginCallHostFunction
, t "Plugin.Multiple" pluginMultiple
, t "Plugin.Update" pluginUpdate
, t "Plugin.Config" pluginConfig

View File

@@ -1,193 +1,194 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.extism.sdk</groupId>
<artifactId>extism</artifactId>
<packaging>jar</packaging>
<version>0.3.0</version>
<name>extism</name>
<url>https://github.com/extism/extism</url>
<description>Java-SDK for Extism to use webassembly from Java</description>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.extism.sdk</groupId>
<artifactId>extism</artifactId>
<packaging>jar</packaging>
<version>0.5.0</version>
<name>extism</name>
<url>https://github.com/extism/extism</url>
<description>Java-SDK for Extism to use webassembly from Java</description>
<licenses>
<license>
<name>BSD 3-Clause</name>
<url>https://opensource.org/licenses/BSD-3-Clause</url>
</license>
</licenses>
<licenses>
<license>
<name>BSD 3-Clause</name>
<url>https://opensource.org/licenses/BSD-3-Clause</url>
</license>
</licenses>
<organization>
<name>Dylibso, Inc.</name>
<url>https://dylib.so</url>
</organization>
<organization>
<name>Dylibso, Inc.</name>
<url>https://dylib.so</url>
</organization>
<developers>
<developer>
<name>The Extism Authors</name>
<email>oss@extism.org</email>
<roles>
<role>Maintainer</role>
</roles>
<organization>Dylibso, Inc.</organization>
<organizationUrl>https://dylib.so</organizationUrl>
</developer>
</developers>
<developers>
<developer>
<name>The Extism Authors</name>
<email>oss@extism.org</email>
<roles>
<role>Maintainer</role>
</roles>
<organization>Dylibso, Inc.</organization>
<organizationUrl>https://dylib.so</organizationUrl>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/extism/extism.git</connection>
<developerConnection>scm:git:ssh://git@github.com/extism/extism.git</developerConnection>
<url>https://github.com/extism/extism/tree/main/java</url>
<tag>main</tag>
</scm>
<scm>
<connection>scm:git:git://github.com/extism/extism.git</connection>
<developerConnection>scm:git:ssh://git@github.com/extism/extism.git</developerConnection>
<url>https://github.com/extism/extism/tree/main/java</url>
<tag>main</tag>
</scm>
<issueManagement>
<system>Github</system>
<url>https://github.com/extism/extism/issues</url>
</issueManagement>
<issueManagement>
<system>Github</system>
<url>https://github.com/extism/extism/issues</url>
</issueManagement>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependencies -->
<jna.version>5.12.1</jna.version>
<gson.version>2.10</gson.version>
<!-- dependencies -->
<jna.version>5.12.1</jna.version>
<gson.version>2.10</gson.version>
<!-- testing -->
<junit-jupiter-engine.version>5.9.1</junit-jupiter-engine.version>
<assertj-core.version>3.23.1</assertj-core.version>
<!-- testing -->
<junit-jupiter-engine.version>5.9.1</junit-jupiter-engine.version>
<assertj-core.version>3.23.1</assertj-core.version>
<!-- maven plugins -->
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<!-- maven plugins -->
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<!-- jreleaser -->
<jreleaser.git.root.search>true</jreleaser.git.root.search>
</properties>
<!-- jreleaser -->
<jreleaser.git.root.search>true</jreleaser.git.root.search>
</properties>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<additionalJOption>-Xdoclint:none</additionalJOption>
</configuration>
<executions>
<execution>
<id>attach-javadoc</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-source</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jreleaser</groupId>
<artifactId>jreleaser-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<jreleaser>
<release>
<github>
<skipRelease>true</skipRelease>
</github>
</release>
<signing>
<active>ALWAYS</active>
<armored>true</armored>
</signing>
<deploy>
<maven>
<nexus2>
<maven-central>
<active>ALWAYS</active>
<url>https://s01.oss.sonatype.org/service/local</url>
<!--
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<additionalJOption>-Xdoclint:none</additionalJOption>
</configuration>
<executions>
<execution>
<id>attach-javadoc</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-source</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jreleaser</groupId>
<artifactId>jreleaser-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<jreleaser>
<release>
<github>
<skipRelease>true</skipRelease>
</github>
</release>
<signing>
<active>ALWAYS</active>
<armored>true</armored>
</signing>
<deploy>
<maven>
<nexus2>
<maven-central>
<active>ALWAYS</active>
<url>https://s01.oss.sonatype.org/service/local</url>
<!--
<closeRepository>false</closeRepository>
<releaseRepository>false</releaseRepository>
-->
<stagingRepositories>target/staging-deploy</stagingRepositories>
</maven-central>
</nexus2>
</maven>
</deploy>
</jreleaser>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<jna.library.path>../target/release</jna.library.path>
</systemPropertyVariables>
</configuration>
</plugin>
<stagingRepositories>target/staging-deploy</stagingRepositories>
</maven-central>
</nexus2>
</maven>
</deploy>
</jreleaser>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter-engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
</build>
</profile>
</profiles>
<dependency>
<groupId>uk.org.webcompere</groupId>
<artifactId>model-assert</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<jna.library.path>../target/release</jna.library.path>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter-engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>uk.org.webcompere</groupId>
<artifactId>model-assert</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -20,10 +20,10 @@ public class PluginTests {
@Test
public void shouldInvokeFunctionWithMemoryOptions() {
//FIXME check whether memory options are effective
var manifest = new Manifest(List.of(CODE.pathWasmSource()), new MemoryOptions(0));
var output = Extism.invokeFunction(manifest, "count_vowels", "Hello World");
assertThat(output).isEqualTo("{\"count\": 3}");
assertThrows(ExtismException.class, () -> {
Extism.invokeFunction(manifest, "count_vowels", "Hello World");
});
}
@Test

2
kernel/.cargo/config Normal file
View File

@@ -0,0 +1,2 @@
[build]
target = "wasm32-unknown-unknown"

11
kernel/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "extism-runtime-kernel"
version = "0.1.0"
edition = "2021"
[dependencies]
[workspace]
members = [
"."
]

20
kernel/README.md Normal file
View File

@@ -0,0 +1,20 @@
# Extism kernel
The Extism kernel implements core parts of the Extism runtime in Rust compiled to WebAssembly. This code is a conceptual
re-write of [memory.rs][] with the goal of making core parts of the Extism implementation more portable across WebAssembly
runtimes.
See [lib.rs][] for more details about the implementation itself.
## Building
Because this crate is built using the `wasm32-unknown-unknown` target, it is a separate build process from the `extism-runtime` crate.
To build `extism-runtime.wasm`, strip it and copy it to the proper location in the `extism-runtime` tree you can run:
```shell
$ sh build.sh
```
[memory.rs]: https://github.com/extism/extism/blob/f4aa139eced4a74eb4a103f78222ba503e146109/runtime/src/memory.rs
[lib.rs]: ./src/lib.rs

7
kernel/build.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
cargo build --release --target wasm32-unknown-unknown --package extism-runtime-kernel --bin extism-runtime
cp target/wasm32-unknown-unknown/release/extism-runtime.wasm .
wasm-strip extism-runtime.wasm
mv extism-runtime.wasm ../runtime/src/extism-runtime.wasm

View File

@@ -0,0 +1,10 @@
#![no_main]
#![no_std]
pub use extism_runtime_kernel::*;
#[cfg(target_arch = "wasm32")]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
core::arch::wasm32::unreachable()
}

525
kernel/src/lib.rs Normal file
View File

@@ -0,0 +1,525 @@
//! # Extism kernel
//!
//! - Isolated memory from both host and plugin
//! - An allocator for managing that memory
//! - Input/output handling
//! - Error message handling
//! - Backward compatible `extism_*` functions
//!
//! ## Allocator
//!
//! The Extism allocator is a bump allocator that tracks the `length` of the total number of bytes
//! available to the allocator and `position` to track how much of the data has been used. Things like memory
//! have not really been optimized at all. When a new allocation that is larger than the remaning size is made,
//! the allocator attempts to call `memory.grow` if that fails a `0` offset is returned, which should be interpreted
//! as a failed allocation.
//!
//! ## Input/Output
//!
//! Input and output are just allocated blocks of memory that are marked as either input or output using
//! the `extism_input_set` or `extism_output_set` functions. The MemoryRoot field `input_offset` contains
//! the offset in memory to the input data and `input_length` contains the size of the input data. `output_offset`
//! and `output_length` are used for the output data.
//!
//! ## Error handling
//!
//! The `error` field is used to track the current error message. If it is set to `0` then there is no error.
//! The length of the error message can be retreived using `extism_length`.
//!
//! ## Memory offsets
//! An offset of `0` is similar to a `NULL` pointer in C - it implies an allocation failure or memory error
//! of some kind
//!
//! ## Extism functions
//!
//! These functions are backward compatible with the pre-kernel runtime, but a few new functions are added to
//! give runtimes more access to the internals necesarry to load data in and out of a plugin.
#![no_std]
#![allow(clippy::missing_safety_doc)]
use core::sync::atomic::*;
pub type Pointer = u64;
pub type Length = u64;
/// WebAssembly page size
const PAGE_SIZE: usize = 65536;
/// Provides information about the usage status of a `MemoryBlock`
#[repr(u8)]
#[derive(PartialEq)]
pub enum MemoryStatus {
/// Unused memory that is available b
Unused = 0,
/// In-use memory
Active = 1,
/// Free memory that is available for re-use
Free = 2,
}
/// A single `MemoryRoot` exists at the start of the memory to track information about the total
/// size of the allocated memory and the position of the bump allocator.
///
/// The overall layout of the Extism-manged memory is organized like this:
/// |------|-------+---------|-------+--------------|
/// | Root | Block + Data | Block + Data | ...
/// |------|-------+---------|-------+--------------|
///
/// Where `Root` and `Block` are fixed to the size of the `MemoryRoot` and `MemoryBlock` structs. But
/// the size of `Data` is dependent on the allocation size.
///
/// This means that the offset of a `Block` is the size of `Root` plus the size of all existing `Blocks`
/// including their data.
#[repr(C)]
pub struct MemoryRoot {
/// Set to true after initialization
pub initialized: AtomicBool,
/// Position of the bump allocator, relative to `blocks` field
pub position: AtomicU64,
/// The total size of all data allocated using this allocator
pub length: AtomicU64,
/// Offset of error block
pub error: AtomicU64,
/// Input position in memory
pub input_offset: Pointer,
/// Input length
pub input_length: Length,
/// Output position in memory
pub output_offset: Pointer,
/// Output length
pub output_length: Length,
/// A pointer to the start of the first block
pub blocks: [MemoryBlock; 0],
}
/// A `MemoryBlock` contains some metadata about a single allocation
#[repr(C)]
pub struct MemoryBlock {
/// The usage status of the block, `Unused` or `Free` blocks can be re-used.
pub status: AtomicU8,
/// The total size of the allocation
pub size: usize,
/// The number of bytes currently being used. If this block is a fresh allocation then `size` and `used` will
/// always be the same. If a block is re-used then these numbers may differ.
pub used: usize,
/// A pointer to the block data
pub data: [u8; 0],
}
/// Returns the number of pages needed for the given number of bytes
pub fn num_pages(nbytes: u64) -> usize {
let npages = nbytes / PAGE_SIZE as u64;
let remainder = nbytes % PAGE_SIZE as u64;
if remainder != 0 {
(npages + 1) as usize
} else {
npages as usize
}
}
// Get the `MemoryRoot`, this is always stored at offset 1 in memory
#[inline]
unsafe fn memory_root() -> &'static mut MemoryRoot {
&mut *(1 as *mut MemoryRoot)
}
impl MemoryRoot {
/// Initialize or load the `MemoryRoot` from the correct position in memory
pub unsafe fn new() -> &'static mut MemoryRoot {
let root = memory_root();
// If this fails then `INITIALIZED` is already `true` and we can just return the
// already initialized `MemoryRoot`
if root
.initialized
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
.is_err()
{
return root;
}
// Ensure that at least one page is allocated to store the `MemoryRoot` data
if core::arch::wasm32::memory_size(0) == 0 {
if core::arch::wasm32::memory_grow(0, 1) == usize::MAX {
core::arch::wasm32::unreachable()
}
}
root.input_offset = 0;
root.input_length = 0;
root.output_offset = 0;
root.output_length = 0;
root.error.store(0, Ordering::Release);
// Initialize the `MemoryRoot` length, position and data
root.length.store(
PAGE_SIZE as u64 - core::mem::size_of::<MemoryRoot>() as u64,
Ordering::Release,
);
root.position.store(0, Ordering::Release);
// Ensure the first block is marked as `Unused`
#[allow(clippy::size_of_in_element_count)]
core::ptr::write_bytes(
root.blocks.as_mut_ptr() as *mut _,
MemoryStatus::Unused as u8,
core::mem::size_of::<MemoryBlock>(),
);
root
}
/// Resets the position of the allocator and zeroes out all allocations
pub unsafe fn reset(&mut self) {
core::ptr::write_bytes(
self.blocks.as_mut_ptr() as *mut u8,
0,
self.length.load(Ordering::Acquire) as usize,
);
self.position.store(0, Ordering::Release);
self.error.store(0, Ordering::Release);
self.input_offset = 0;
self.input_length = 0;
self.output_offset = 0;
self.output_length = 0;
}
#[inline(always)]
#[allow(unused)]
fn pointer_in_bounds(&self, p: Pointer) -> bool {
let start_ptr = self.blocks.as_ptr() as Pointer;
p >= start_ptr && p < start_ptr + self.length.load(Ordering::Acquire) as Pointer
}
#[inline(always)]
#[allow(unused)]
fn pointer_in_bounds_fast(p: Pointer) -> bool {
// Similar to `pointer_in_bounds` but less accurate on the upper bound. This uses the total memory size,
// instead of checking `MemoryRoot::length`
let end = core::arch::wasm32::memory_size(0) << 16;
p >= core::mem::size_of::<Self>() as Pointer && p <= end as Pointer
}
// Find a block that is free to use, this can be a new block or an existing freed block. The `self_position` argument
// is used to avoid loading the allocators position more than once when performing an allocation.
unsafe fn find_free_block(
&mut self,
length: Length,
self_position: u64,
) -> Option<&'static mut MemoryBlock> {
// Get the first block
let mut block = self.blocks.as_mut_ptr();
// Only loop while the block pointer is less then the current position
while (block as u64) < self.blocks.as_ptr() as u64 + self_position {
let b = &mut *block;
// Get the block status, this lets us know if we are able to re-use it
let status = b.status.load(Ordering::Acquire);
// An unused block is safe to use
if status == MemoryStatus::Unused as u8 {
return Some(b);
}
// Re-use freed blocks when they're large enough
if status == MemoryStatus::Free as u8 && b.size >= length as usize {
// Split block if there is too much excess
if b.size - length as usize >= 128 {
b.size -= length as usize;
b.used = 0;
let block1 = b.data.as_mut_ptr().add(b.size) as *mut MemoryBlock;
let b1 = &mut *block1;
b1.size = length as usize;
b1.used = 0;
b1.status.store(MemoryStatus::Free as u8, Ordering::Release);
return Some(b1);
}
// Otherwise return the whole block
return Some(b);
}
// Get the next block
block = b.next_ptr();
}
None
}
/// Create a new `MemoryBlock`, when `Some(block)` is returned, `block` will contain at least enough room for `length` bytes
/// but may be as large as `length` + `BLOCK_SPLIT_SIZE` bytes. When `None` is returned the allocation has failed.
pub unsafe fn alloc(&mut self, length: Length) -> Option<&'static mut MemoryBlock> {
let self_position = self.position.load(Ordering::Acquire);
let self_length = self.length.load(Ordering::Acquire);
let b = self.find_free_block(length, self_position);
// If there's a free block then re-use it
if let Some(b) = b {
b.used = length as usize;
b.status
.store(MemoryStatus::Active as u8, Ordering::Release);
return Some(b);
}
// Get the current index for a new block
let curr = self.blocks.as_ptr() as u64 + self_position;
// Get the number of bytes available
let mem_left = self_length - self_position - core::mem::size_of::<MemoryRoot>() as u64;
// When the allocation is larger than the number of bytes available
// we will need to try to grow the memory
if length >= mem_left {
// Calculate the number of pages needed to cover the remaining bytes
let npages = num_pages(length - mem_left);
let x = core::arch::wasm32::memory_grow(0, npages);
if x == usize::MAX {
return None;
}
self.length
.fetch_add(npages as u64 * PAGE_SIZE as u64, Ordering::SeqCst);
}
// Bump the position by the size of the actual data + the size of the MemoryBlock structure
self.position.fetch_add(
length + core::mem::size_of::<MemoryBlock>() as u64,
Ordering::SeqCst,
);
// Initialize a new block at the current position
let ptr = curr as *mut MemoryBlock;
let block = &mut *ptr;
block
.status
.store(MemoryStatus::Active as u8, Ordering::Release);
block.size = length as usize;
block.used = length as usize;
Some(block)
}
/// Finds the block at an offset in memory
pub unsafe fn find_block(&mut self, offs: Pointer) -> Option<&mut MemoryBlock> {
if !Self::pointer_in_bounds_fast(offs) {
return None;
}
let ptr = offs - core::mem::size_of::<MemoryBlock>() as u64;
let ptr = ptr as *mut MemoryBlock;
Some(&mut *ptr)
}
}
impl MemoryBlock {
/// Get a pointer to the next block
///
/// NOTE: This does no checking to ensure the resulting pointer is valid, the offset
/// is calculated based on metadata provided by the current block
#[inline]
pub unsafe fn next_ptr(&mut self) -> *mut MemoryBlock {
self.data.as_mut_ptr().add(self.size) as *mut MemoryBlock
}
/// Mark a block as free
pub fn free(&mut self) {
self.status
.store(MemoryStatus::Free as u8, Ordering::Release);
}
}
// Extism functions
/// Allocate a block of memory and return the offset
#[no_mangle]
pub unsafe fn extism_alloc(n: Length) -> Pointer {
if n == 0 {
return 0;
}
let region = MemoryRoot::new();
let block = region.alloc(n);
match block {
Some(block) => block.data.as_mut_ptr() as Pointer,
None => 0,
}
}
/// Free allocated memory
#[no_mangle]
pub unsafe fn extism_free(p: Pointer) {
if p == 0 {
return;
}
let root = MemoryRoot::new();
let block = root.find_block(p);
if let Some(block) = block {
block.free();
// If the input pointer is freed for some reason, make sure the input length to 0
// since the original data is gone
if p == root.input_offset {
root.input_length = 0;
}
}
}
/// Get the length of an allocated memory block
#[no_mangle]
pub unsafe fn extism_length(p: Pointer) -> Length {
if p == 0 {
return 0;
}
if let Some(block) = MemoryRoot::new().find_block(p) {
block.used as Length
} else {
0
}
}
/// Load a byte from Extism-managed memory
#[no_mangle]
pub unsafe fn extism_load_u8(p: Pointer) -> u8 {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p) {
return 0;
}
*(p as *mut u8)
}
/// Load a u64 from Extism-managed memory
#[no_mangle]
pub unsafe fn extism_load_u64(p: Pointer) -> u64 {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p + core::mem::size_of::<u64>() as u64 - 1) {
return 0;
}
*(p as *mut u64)
}
/// Load a byte from the input data
#[no_mangle]
pub unsafe fn extism_input_load_u8(p: Pointer) -> u8 {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
if p >= root.input_length {
return 0;
}
*((root.input_offset + p) as *mut u8)
}
/// Load a u64 from the input data
#[no_mangle]
pub unsafe fn extism_input_load_u64(p: Pointer) -> u64 {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
if p + core::mem::size_of::<u64>() as Pointer > root.input_length {
return 0;
}
*((root.input_offset + p) as *mut u64)
}
/// Write a byte in Extism-managed memory
#[no_mangle]
pub unsafe fn extism_store_u8(p: Pointer, x: u8) {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p) {
return;
}
*(p as *mut u8) = x;
}
/// Write a u64 in Extism-managed memory
#[no_mangle]
pub unsafe fn extism_store_u64(p: Pointer, x: u64) {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p + core::mem::size_of::<u64>() as u64 - 1) {
return;
}
*(p as *mut u64) = x;
}
/// Set the range of the input data in memory
#[no_mangle]
pub unsafe fn extism_input_set(p: Pointer, len: Length) {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
{
if !root.pointer_in_bounds(p) || !root.pointer_in_bounds(p + len - 1) {
return;
}
}
root.input_offset = p;
root.input_length = len;
}
/// Set the range of the output data in memory
#[no_mangle]
pub unsafe fn extism_output_set(p: Pointer, len: Length) {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
{
if !root.pointer_in_bounds(p) || !root.pointer_in_bounds(p + len - 1) {
return;
}
}
root.output_offset = p;
root.output_length = len;
}
/// Get the input length
#[no_mangle]
pub fn extism_input_length() -> Length {
unsafe { MemoryRoot::new().input_length }
}
/// Get the input offset in Exitsm-managed memory
#[no_mangle]
pub fn extism_input_offset() -> Length {
unsafe { MemoryRoot::new().input_offset }
}
/// Get the output length
#[no_mangle]
pub unsafe fn extism_output_length() -> Length {
unsafe { MemoryRoot::new().output_length }
}
/// Get the output offset in Extism-managed memory
#[no_mangle]
pub unsafe fn extism_output_offset() -> Length {
MemoryRoot::new().output_offset
}
/// Reset the allocator
#[no_mangle]
pub unsafe fn extism_reset() {
MemoryRoot::new().reset()
}
/// Set the error message offset
#[no_mangle]
pub unsafe fn extism_error_set(ptr: Pointer) {
let root = MemoryRoot::new();
// Allow ERROR to be set to 0
if ptr == 0 {
root.error.store(ptr, Ordering::SeqCst);
return;
}
if !root.pointer_in_bounds(ptr) {
return;
}
root.error.store(ptr, Ordering::SeqCst);
}
/// Get the error message offset, if it's `0` then no error has been set
#[no_mangle]
pub unsafe fn extism_error_get() -> Pointer {
MemoryRoot::new().error.load(Ordering::SeqCst)
}
/// Get the position of the allocator, this can be used as an indication of how many bytes are currently in-use
#[no_mangle]
pub unsafe fn extism_memory_bytes() -> Length {
MemoryRoot::new().position.load(Ordering::Acquire)
}

View File

@@ -1,6 +1,6 @@
[package]
name = "libextism"
version = "0.3.0"
version = "0.5.4"
edition = "2021"
authors = ["The Extism Authors", "oss@extism.org"]
license = "BSD-3-Clause"

View File

@@ -1,6 +1,6 @@
[package]
name = "extism-manifest"
version = "0.3.0"
version = "0.5.0"
edition = "2021"
authors = ["The Extism Authors", "oss@extism.org"]
license = "BSD-3-Clause"

View File

@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
#[deprecated]
pub type ManifestMemory = MemoryOptions;
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct MemoryOptions {
@@ -12,7 +12,7 @@ pub struct MemoryOptions {
pub max_pages: Option<u32>,
}
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct HttpRequest {
@@ -43,7 +43,7 @@ impl HttpRequest {
}
}
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct WasmMetadata {
@@ -81,7 +81,7 @@ impl From<Vec<u8>> for Wasm {
#[deprecated]
pub type ManifestWasm = Wasm;
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(untagged)]
#[serde(deny_unknown_fields)]
@@ -153,7 +153,7 @@ fn base64_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::
schema.into()
}
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct Manifest {

769
node/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@extism/extism",
"version": "0.3.0",
"version": "0.5.0",
"description": "Extism Host SDK for Node",
"keywords": [
"extism",
@@ -41,7 +41,7 @@
"@types/jest": "^29.2.0",
"@types/node": "^20.1.0",
"jest": "^29.2.2",
"prettier": "2.8.8",
"prettier": "3.0.2",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typedoc": "^0.24.1",

View File

@@ -1,5 +1,5 @@
VERSION?=0.2.0
TAG?=0.3.0
VERSION?=0.4.0
TAG?=0.5.0
build:
dune build

View File

@@ -77,7 +77,9 @@ let update plugin ?config ?(wasi = false) ?(functions = []) wasm =
| Some msg -> Error (`Msg msg)
else if not (set_config plugin config) then
Error (`Msg "call to set_config failed")
else Ok ()
else
let () = plugin.functions <- functions in
Ok ()
let update_manifest plugin ?wasi manifest =
let data = Manifest.to_json manifest in

View File

@@ -1,3 +1,5 @@
open Ppx_yojson_conv_lib.Yojson_conv
type base64 = string
let yojson_of_base64 x = `String (Base64.encode_exn x)

View File

@@ -2,9 +2,8 @@
require_once __DIR__ . '/vendor/autoload.php';
$ctx = new \Extism\Context();
$wasm = file_get_contents("../../wasm/code.wasm");
$plugin = new \Extism\Plugin($ctx, $wasm);
$plugin = new \Extism\Plugin($wasm);
$output = $plugin->call("count_vowels", "this is an example");
$json = json_decode(pack('C*', ...$output));

View File

@@ -5,7 +5,9 @@ import hashlib
import pathlib
sys.path.append(".")
from extism import Function, host_fn, ValType, Plugin
from extism import Function, host_fn, ValType, Plugin, set_log_file
set_log_file("stderr", "trace")
@host_fn
@@ -26,14 +28,14 @@ def main(args):
if len(args) > 1:
data = args[1].encode()
else:
data = b"some data from python!"
data = b"a" * 1024
wasm_file_path = (
pathlib.Path(__file__).parent.parent / "wasm" / "code-functions.wasm"
)
wasm = wasm_file_path.read_bytes()
hash = hashlib.sha256(wasm).hexdigest()
manifest = {"wasm": [{"data": wasm, "hash": hash}], "memory": {"max": 5}}
manifest = {"wasm": [{"data": wasm, "hash": hash}]}
functions = [
Function(
@@ -46,11 +48,13 @@ def main(args):
]
plugin = Plugin(manifest, wasi=True, functions=functions)
# Call `count_vowels`
wasm_vowel_count = json.loads(plugin.call("count_vowels", data))
wasm_vowel_count = plugin.call("count_vowels", data)
print(wasm_vowel_count)
j = json.loads(wasm_vowel_count)
print("Number of vowels:", wasm_vowel_count["count"])
print("Number of vowels:", j["count"])
assert wasm_vowel_count["count"] == count_vowels(data)
assert j["count"] == count_vowels(data)
if __name__ == "__main__":

View File

@@ -263,6 +263,7 @@ class Plugin:
context = Context()
wasm = _wasm(plugin)
self.functions = functions
# Register plugin
if functions is not None:
@@ -310,6 +311,7 @@ class Plugin:
"""
wasm = _wasm(manifest)
if functions is not None:
self.functions = functions
functions = [f.pointer for f in functions]
ptr = _ffi.new("ExtismFunction*[]", functions)
ok = _lib.extism_plugin_update(

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "extism"
version = "0.3.0"
version = "0.5.0"
description = "Extism Host SDK for python"
authors = ["The Extism Authors <oss@extism.org>"]
license = "BSD-3-Clause"

View File

@@ -115,14 +115,13 @@ class TestExtism(unittest.TestCase):
def _manifest(self, functions=False):
wasm = self._count_vowels_wasm(functions)
hash = hashlib.sha256(wasm).hexdigest()
return {"wasm": [{"data": wasm, "hash": hash}], "memory": {"max_pages": 5}}
return {"wasm": [{"data": wasm, "hash": hash}]}
def _loop_manifest(self):
wasm = self._infinite_loop_wasm()
hash = hashlib.sha256(wasm).hexdigest()
return {
"wasm": [{"data": wasm, "hash": hash}],
"memory": {"max_pages": 5},
"timeout_ms": 1000,
}

View File

@@ -11,5 +11,5 @@ gem "ffi", "~> 1.15.5"
group :development do
gem "yard", "~> 0.9.28"
gem "rufo", "~> 0.13.0"
gem "minitest", "~> 5.18.0"
gem "minitest", "~> 5.19.0"
end

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Extism
VERSION = "0.3.0"
VERSION = '0.5.0'
end

View File

@@ -1,6 +1,6 @@
[package]
name = "extism-runtime"
version = "0.4.0"
version = "0.5.5"
edition = "2021"
authors = ["The Extism Authors", "oss@extism.org"]
license = "BSD-3-Clause"
@@ -9,9 +9,9 @@ repository = "https://github.com/extism/extism"
description = "Extism runtime component"
[dependencies]
wasmtime = "8.0.0"
wasmtime-wasi = "8.0.0"
wasmtime-wasi-nn = {version = "8.0.0", optional=true}
wasmtime = ">= 10.0.0, < 12.0.0"
wasmtime-wasi = ">= 10.0.0, < 12.0.0"
wasmtime-wasi-nn = {version = ">= 10.0.0, < 12.0.0", optional=true}
anyhow = "1"
serde = {version = "1", features = ["derive"]}
serde_json = "1"
@@ -22,8 +22,7 @@ log4rs = "1.1"
url = "2"
glob = "0.3"
ureq = {version = "2.5", optional=true}
extism-manifest = { version = "0.3.0", path = "../manifest" }
pretty-hex = { version = "0.3" }
extism-manifest = { version = "0.5.0", path = "../manifest" }
uuid = { version = "1", features = ["v4"] }
libc = "0.2"

View File

@@ -1,4 +1,6 @@
fn main() {
println!("cargo:rerun-if-changed=src/extism-runtime.wasm");
let fn_macro = "
#define EXTISM_FUNCTION(N) extern void N(ExtismCurrentPlugin*, const ExtismVal*, ExtismSize, ExtismVal*, ExtismSize, void*)
#define EXTISM_GO_FUNCTION(N) extern void N(void*, ExtismVal*, ExtismSize, ExtismVal*, ExtismSize, uintptr_t)

View File

@@ -81,7 +81,12 @@ typedef struct {
/**
* Host function signature
*/
typedef void (*ExtismFunctionType)(ExtismCurrentPlugin *plugin, const ExtismVal *inputs, ExtismSize n_inputs, ExtismVal *outputs, ExtismSize n_outputs, void *data);
typedef void (*ExtismFunctionType)(ExtismCurrentPlugin *plugin,
const ExtismVal *inputs,
ExtismSize n_inputs,
ExtismVal *outputs,
ExtismSize n_outputs,
void *data);
typedef int32_t ExtismPlugin;
@@ -245,7 +250,7 @@ const char *extism_error(ExtismContext *ctx, ExtismPlugin plugin);
ExtismSize extism_plugin_output_length(ExtismContext *ctx, ExtismPlugin plugin);
/**
* Get the length of a plugin's output data
* Get a pointer to the output data
*/
const uint8_t *extism_plugin_output_data(ExtismContext *ctx, ExtismPlugin plugin);

BIN
runtime/src/extism-runtime.wasm Executable file

Binary file not shown.

View File

@@ -2,58 +2,6 @@ use std::collections::BTreeMap;
use crate::*;
/// Internal stores data that is available to the caller in PDK functions
pub struct Internal {
/// Call input length
pub input_length: usize,
/// Pointer to call input
pub input: *const u8,
/// Memory offset that points to the output
pub output_offset: usize,
/// Length of output in memory
pub output_length: usize,
/// WASI context
pub wasi: Option<Wasi>,
/// Keep track of the status from the last HTTP request
pub http_status: u16,
/// Store plugin-specific error messages
pub last_error: std::cell::RefCell<Option<std::ffi::CString>>,
/// Plugin variables
pub vars: BTreeMap<String, Vec<u8>>,
/// A pointer to the plugin memory, this should mostly be used from the PDK
pub memory: *mut PluginMemory,
}
/// InternalExt provides a unified way of acessing `memory`, `store` and `internal` values
pub trait InternalExt {
fn memory(&self) -> &PluginMemory;
fn memory_mut(&mut self) -> &mut PluginMemory;
fn store(&self) -> &Store<Internal> {
self.memory().store()
}
fn store_mut(&mut self) -> &mut Store<Internal> {
self.memory_mut().store_mut()
}
fn internal(&self) -> &Internal {
self.store().data()
}
fn internal_mut(&mut self) -> &mut Internal {
self.store_mut().data_mut()
}
}
/// WASI context
pub struct Wasi {
/// wasi
@@ -62,12 +10,222 @@ pub struct Wasi {
/// wasi-nn
#[cfg(feature = "nn")]
pub nn: wasmtime_wasi_nn::WasiNnCtx,
#[cfg(not(feature = "nn"))]
pub nn: (),
}
/// Internal stores data that is available to the caller in PDK functions
pub struct Internal {
/// Store
pub store: *mut Store<Internal>,
/// Linker
pub linker: *mut wasmtime::Linker<Internal>,
/// WASI context
pub wasi: Option<Wasi>,
/// Keep track of the status from the last HTTP request
pub http_status: u16,
/// Plugin variables
pub vars: BTreeMap<String, Vec<u8>>,
pub manifest: Manifest,
pub available_pages: Option<u32>,
pub(crate) memory_limiter: Option<MemoryLimiter>,
}
/// InternalExt provides a unified way of acessing `memory`, `store` and `internal` values
pub trait InternalExt {
fn store(&self) -> &Store<Internal>;
fn store_mut(&mut self) -> &mut Store<Internal>;
fn linker(&self) -> &Linker<Internal>;
fn linker_mut(&mut self) -> &mut Linker<Internal>;
fn linker_and_store(&mut self) -> (&mut Linker<Internal>, &mut Store<Internal>);
fn internal(&self) -> &Internal {
self.store().data()
}
fn internal_mut(&mut self) -> &mut Internal {
self.store_mut().data_mut()
}
fn memory_ptr(&mut self) -> *mut u8 {
let (linker, mut store) = self.linker_and_store();
if let Some(mem) = linker.get(&mut store, "env", "memory") {
if let Some(mem) = mem.into_memory() {
return mem.data_ptr(&mut store);
}
}
std::ptr::null_mut()
}
fn memory(&mut self) -> &mut [u8] {
let (linker, mut store) = self.linker_and_store();
let mem = linker
.get(&mut store, "env", "memory")
.unwrap()
.into_memory()
.unwrap();
let ptr = mem.data_ptr(&store);
if ptr.is_null() {
return &mut [];
}
let size = mem.data_size(&store);
unsafe { std::slice::from_raw_parts_mut(ptr, size) }
}
fn memory_read(&mut self, offs: u64, len: Size) -> &[u8] {
trace!("memory_read: {}, {}", offs, len);
let offs = offs as usize;
let len = len as usize;
let mem = self.memory();
&mem[offs..offs + len]
}
fn memory_read_str(&mut self, offs: u64) -> Result<&str, std::str::Utf8Error> {
let len = self.memory_length(offs);
std::str::from_utf8(self.memory_read(offs, len))
}
fn memory_write(&mut self, offs: u64, bytes: impl AsRef<[u8]>) {
trace!("memory_write: {}", offs);
let b = bytes.as_ref();
let offs = offs as usize;
let len = b.len();
self.memory()[offs..offs + len].copy_from_slice(bytes.as_ref());
}
fn memory_alloc(&mut self, n: Size) -> Result<u64, Error> {
if n == 0 {
return Ok(0);
}
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
linker
.get(&mut store, "env", "extism_alloc")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[Val::I64(n as i64)], output)?;
let offs = output[0].unwrap_i64() as u64;
if offs == 0 && n > 0 {
anyhow::bail!("out of memory")
}
trace!("memory_alloc: {}, {}", offs, n);
Ok(offs)
}
fn memory_alloc_bytes(&mut self, bytes: impl AsRef<[u8]>) -> Result<u64, Error> {
let b = bytes.as_ref();
let offs = self.memory_alloc(b.len() as Size)?;
self.memory_write(offs, b);
Ok(offs)
}
fn memory_free(&mut self, offs: u64) {
let (linker, mut store) = self.linker_and_store();
linker
.get(&mut store, "env", "extism_free")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[Val::I64(offs as i64)], &mut [])
.unwrap();
}
fn memory_length(&mut self, offs: u64) -> u64 {
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
linker
.get(&mut store, "env", "extism_length")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[Val::I64(offs as i64)], output)
.unwrap();
let len = output[0].unwrap_i64() as u64;
trace!("memory_length: {}, {}", offs, len);
len
}
// A convenience method to set the plugin error and return a value
fn error<E>(&mut self, e: impl std::fmt::Debug, x: E) -> E {
let s = format!("{e:?}");
debug!("Set error: {:?}", s);
if let Ok(offs) = self.memory_alloc_bytes(&s) {
let (linker, mut store) = self.linker_and_store();
if let Some(f) = linker.get(&mut store, "env", "extism_error_set") {
f.into_func()
.unwrap()
.call(&mut store, &[Val::I64(offs as i64)], &mut [])
.unwrap();
}
}
x
}
fn clear_error(&mut self) {
let (linker, mut store) = self.linker_and_store();
if let Some(f) = linker.get(&mut store, "env", "extism_error_set") {
f.into_func()
.unwrap()
.call(&mut store, &[Val::I64(0)], &mut [])
.unwrap();
}
}
fn has_error(&mut self) -> bool {
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
linker
.get(&mut store, "env", "extism_error_get")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[], output)
.unwrap();
output[0].unwrap_i64() != 0
}
fn get_error(&mut self) -> Option<&str> {
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
linker
.get(&mut store, "env", "extism_error_get")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[], output)
.unwrap();
let offs = output[0].unwrap_i64() as u64;
if offs == 0 {
return None;
}
let length = self.memory_length(offs);
let data = self.memory_read(offs, length);
let s = std::str::from_utf8(data);
match s {
Ok(s) => Some(s),
Err(_) => None,
}
}
}
impl Internal {
pub(crate) fn new(manifest: &Manifest, wasi: bool) -> Result<Self, Error> {
pub(crate) fn new(
manifest: Manifest,
wasi: bool,
available_pages: Option<u32>,
) -> Result<Self, Error> {
let wasi = if wasi {
let auth = wasmtime_wasi::ambient_authority();
let mut ctx = wasmtime_wasi::WasiCtxBuilder::new();
@@ -85,48 +243,106 @@ impl Internal {
#[cfg(feature = "nn")]
let nn = wasmtime_wasi_nn::WasiNnCtx::new()?;
#[cfg(not(feature = "nn"))]
#[allow(clippy::let_unit_value)]
let nn = ();
Some(Wasi {
ctx: ctx.build(),
#[cfg(feature = "nn")]
nn,
})
} else {
None
};
let memory_limiter = if let Some(pgs) = available_pages {
let n = pgs as usize * 65536;
Some(MemoryLimiter {
max_bytes: n,
bytes_left: n,
})
} else {
None
};
Ok(Internal {
input_length: 0,
output_offset: 0,
output_length: 0,
input: std::ptr::null(),
wasi,
memory: std::ptr::null_mut(),
manifest,
http_status: 0,
last_error: std::cell::RefCell::new(None),
vars: BTreeMap::new(),
linker: std::ptr::null_mut(),
store: std::ptr::null_mut(),
available_pages,
memory_limiter,
})
}
pub fn set_error(&self, e: impl std::fmt::Debug) {
debug!("Set error: {:?}", e);
*self.last_error.borrow_mut() = Some(error_string(e));
pub fn linker(&self) -> &wasmtime::Linker<Internal> {
unsafe { &*self.linker }
}
/// Unset `last_error` field
pub fn clear_error(&self) {
*self.last_error.borrow_mut() = None;
pub fn linker_mut(&mut self) -> &mut wasmtime::Linker<Internal> {
unsafe { &mut *self.linker }
}
}
impl InternalExt for Internal {
fn memory(&self) -> &PluginMemory {
unsafe { &*self.memory }
fn store(&self) -> &Store<Internal> {
unsafe { &*self.store }
}
fn memory_mut(&mut self) -> &mut PluginMemory {
unsafe { &mut *self.memory }
fn store_mut(&mut self) -> &mut Store<Internal> {
unsafe { &mut *self.store }
}
fn linker(&self) -> &Linker<Internal> {
unsafe { &*self.linker }
}
fn linker_mut(&mut self) -> &mut Linker<Internal> {
unsafe { &mut *self.linker }
}
fn linker_and_store(&mut self) -> (&mut Linker<Internal>, &mut Store<Internal>) {
unsafe { (&mut *self.linker, &mut *self.store) }
}
}
pub(crate) struct MemoryLimiter {
bytes_left: usize,
max_bytes: usize,
}
impl MemoryLimiter {
pub(crate) fn reset(&mut self) {
self.bytes_left = self.max_bytes;
}
}
impl wasmtime::ResourceLimiter for MemoryLimiter {
fn memory_growing(
&mut self,
current: usize,
desired: usize,
maximum: Option<usize>,
) -> Result<bool> {
if let Some(max) = maximum {
if desired > max {
return Ok(false);
}
}
let d = desired - current;
if d > self.bytes_left {
return Ok(false);
}
self.bytes_left -= d;
Ok(true)
}
fn table_growing(&mut self, _current: u32, desired: u32, maximum: Option<u32>) -> Result<bool> {
if let Some(max) = maximum {
return Ok(desired <= max);
}
Ok(true)
}
}

View File

@@ -5,7 +5,6 @@ mod context;
mod function;
mod internal;
pub mod manifest;
mod memory;
pub(crate) mod pdk;
mod plugin;
mod plugin_ref;
@@ -16,7 +15,6 @@ pub use context::Context;
pub use function::{Function, UserData, Val, ValType};
pub use internal::{Internal, InternalExt, Wasi};
pub use manifest::Manifest;
pub use memory::{MemoryBlock, PluginMemory, ToMemoryBlock};
pub use plugin::Plugin;
pub use plugin_ref::PluginRef;
pub(crate) use timer::{Timer, TimerAction};

View File

@@ -7,7 +7,7 @@ use sha2::Digest;
use crate::*;
/// Manifest wraps the manifest exported by `extism_manifest`
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct Manifest(extism_manifest::Manifest);
@@ -60,6 +60,8 @@ fn check_hash(hash: &Option<String>, data: &[u8]) -> Result<(), Error> {
}
}
const WASM: &[u8] = include_bytes!("extism-runtime.wasm");
/// Convert from manifest to a wasmtime Module
fn to_module(engine: &Engine, wasm: &extism_manifest::Wasm) -> Result<(String, Module), Error> {
match wasm {
@@ -167,6 +169,7 @@ const WASM_MAGIC: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
impl Manifest {
/// Create a new Manifest, returns the manifest and a map of modules
pub fn new(engine: &Engine, data: &[u8]) -> Result<(Self, BTreeMap<String, Module>), Error> {
let extism_module = Module::new(engine, WASM)?;
let has_magic = data.len() >= 4 && data[0..4] == WASM_MAGIC;
let is_wast = data.starts_with(b"(module") || data.starts_with(b";;");
if !has_magic && !is_wast {
@@ -178,12 +181,14 @@ impl Manifest {
}
let t = serde_json::from_slice::<Self>(data)?;
let m = t.modules(engine)?;
let mut m = t.modules(engine)?;
m.insert("env".to_string(), extism_module);
return Ok((t, m));
}
let m = Module::new(engine, data)?;
let mut modules = BTreeMap::new();
modules.insert("env".to_string(), extism_module);
modules.insert("main".to_string(), m);
Ok((Manifest::default(), modules))
}

View File

@@ -1,378 +0,0 @@
use std::collections::BTreeMap;
use crate::*;
use pretty_hex::PrettyHex;
/// Handles memory for plugins
pub struct PluginMemory {
/// wasmtime Store
pub store: Option<Store<Internal>>,
/// WASM memory
pub memory: Memory,
/// Tracks allocated blocks
pub live_blocks: BTreeMap<usize, usize>,
/// Tracks free blocks
pub free: Vec<MemoryBlock>,
/// Tracks current offset in memory
pub position: usize,
/// Extism manifest
pub manifest: Manifest,
}
/// `ToMemoryBlock` is used to convert from Rust values to blocks of WASM memory
pub trait ToMemoryBlock {
fn to_memory_block(&self, mem: &PluginMemory) -> Result<MemoryBlock, Error>;
}
impl ToMemoryBlock for MemoryBlock {
fn to_memory_block(&self, _mem: &PluginMemory) -> Result<MemoryBlock, Error> {
Ok(*self)
}
}
impl ToMemoryBlock for (usize, usize) {
fn to_memory_block(&self, _mem: &PluginMemory) -> Result<MemoryBlock, Error> {
Ok(MemoryBlock {
offset: self.0,
length: self.1,
})
}
}
impl ToMemoryBlock for usize {
fn to_memory_block(&self, mem: &PluginMemory) -> Result<MemoryBlock, Error> {
match mem.at_offset(*self) {
Some(x) => Ok(x),
None => Err(Error::msg(format!("Invalid memory offset: {}", self))),
}
}
}
const PAGE_SIZE: u32 = 65536;
// BLOCK_SIZE_THRESHOLD exists to ensure that free blocks are never split up any
// smaller than this value
const BLOCK_SIZE_THRESHOLD: usize = 32;
impl PluginMemory {
/// Create memory for a plugin
pub fn new(store: Store<Internal>, memory: Memory, manifest: Manifest) -> Self {
PluginMemory {
free: Vec::new(),
live_blocks: BTreeMap::new(),
store: Some(store),
memory,
position: 1,
manifest,
}
}
pub fn store(&self) -> &Store<Internal> {
self.store.as_ref().unwrap()
}
pub fn store_mut(&mut self) -> &mut Store<Internal> {
self.store.as_mut().unwrap()
}
/// Moves module to a new store
pub fn reinstantiate(&mut self) -> Result<(), Error> {
if let Some(store) = self.store.take() {
let engine = store.engine().clone();
let internal = store.into_data();
let mut store = Store::new(&engine, internal);
store.epoch_deadline_callback(|_internal| Err(Error::msg("timeout")));
self.memory = Memory::new(
&mut store,
MemoryType::new(4, self.manifest.as_ref().memory.max_pages),
)?;
self.store = Some(store);
}
self.reset();
Ok(())
}
/// Write byte to memory
pub(crate) fn store_u8(&mut self, offs: usize, data: u8) -> Result<(), MemoryAccessError> {
trace!("store_u8: offset={offs} data={data:#04x}");
if offs >= self.size() {
// This should raise MemoryAccessError
let buf = &mut [0];
self.memory.read(&self.store.as_ref().unwrap(), offs, buf)?;
return Ok(());
}
self.memory.data_mut(&mut self.store.as_mut().unwrap())[offs] = data;
Ok(())
}
/// Read byte from memory
pub(crate) fn load_u8(&self, offs: usize) -> Result<u8, MemoryAccessError> {
trace!("load_u8: offset={offs}");
if offs >= self.size() {
// This should raise MemoryAccessError
let buf = &mut [0];
self.memory.read(&self.store.as_ref().unwrap(), offs, buf)?;
return Ok(0);
}
Ok(self.memory.data(&self.store.as_ref().unwrap())[offs])
}
/// Write u64 to memory
pub(crate) fn store_u64(&mut self, offs: usize, data: u64) -> Result<(), Error> {
trace!("store_u64: offset={offs} data={data:#18x}");
let handle = MemoryBlock {
offset: offs,
length: 8,
};
self.write(handle, data.to_ne_bytes())?;
Ok(())
}
/// Read u64 from memory
pub(crate) fn load_u64(&self, offs: usize) -> Result<u64, Error> {
trace!("load_u64: offset={offs}");
let mut buf = [0; 8];
let handle = MemoryBlock {
offset: offs,
length: 8,
};
self.read(handle, &mut buf)?;
Ok(u64::from_ne_bytes(buf))
}
/// Write slice to memory
pub fn write(&mut self, pos: impl ToMemoryBlock, data: impl AsRef<[u8]>) -> Result<(), Error> {
let pos = pos.to_memory_block(self)?;
assert!(data.as_ref().len() <= pos.length);
self.memory
.write(&mut self.store.as_mut().unwrap(), pos.offset, data.as_ref())?;
Ok(())
}
/// Read slice from memory
pub fn read(&self, pos: impl ToMemoryBlock, mut data: impl AsMut<[u8]>) -> Result<(), Error> {
let pos = pos.to_memory_block(self)?;
assert!(data.as_mut().len() <= pos.length);
self.memory
.read(&self.store.as_ref().unwrap(), pos.offset, data.as_mut())?;
Ok(())
}
/// Size of memory in bytes
pub fn size(&self) -> usize {
self.memory.data_size(&self.store.as_ref().unwrap())
}
/// Size of memory in pages
pub fn pages(&self) -> u32 {
self.memory.size(&self.store.as_ref().unwrap()) as u32
}
/// Reserve `n` bytes of memory
pub fn alloc(&mut self, n: usize) -> Result<MemoryBlock, Error> {
debug!("Allocating {n} bytes");
for (i, block) in self.free.iter_mut().enumerate() {
if block.length == n {
let block = self.free.swap_remove(i);
self.live_blocks.insert(block.offset, block.length);
debug!("Found block with exact size at offset {}", block.offset);
return Ok(block);
} else if block.length.saturating_sub(n) >= BLOCK_SIZE_THRESHOLD {
let handle = MemoryBlock {
offset: block.offset,
length: n,
};
debug!(
"Using block with size {} at offset {}",
block.length, block.offset
);
block.offset += n;
block.length -= n;
self.live_blocks.insert(handle.offset, handle.length);
return Ok(handle);
}
}
let new_offset = self.position.saturating_add(n);
// If there aren't enough bytes, try to grow the memory size
if new_offset >= self.size() {
debug!("Need more memory");
let bytes_needed = (new_offset as f64 - self.size() as f64) / PAGE_SIZE as f64;
let mut pages_needed = bytes_needed.ceil() as u64;
if pages_needed == 0 {
pages_needed = 1
}
debug!("Requesting {pages_needed} more pages");
// This will fail if we've already allocated the maximum amount of memory allowed
self.memory
.grow(&mut self.store.as_mut().unwrap(), pages_needed)?;
}
let mem = MemoryBlock {
offset: self.position,
length: n,
};
debug!(
"Allocated new block: {} bytes at offset {}",
mem.length, mem.offset
);
self.live_blocks.insert(mem.offset, mem.length);
self.position += n;
Ok(mem)
}
/// Allocate and copy `data` into the wasm memory
pub fn alloc_bytes(&mut self, data: impl AsRef<[u8]>) -> Result<MemoryBlock, Error> {
let handle = self.alloc(data.as_ref().len())?;
self.write(handle, data)?;
Ok(handle)
}
/// Free the block allocated at `offset`
pub fn free(&mut self, offset: usize) {
debug!("Freeing block at {offset}");
if let Some(length) = self.live_blocks.remove(&offset) {
self.free.push(MemoryBlock { offset, length });
} else {
return;
}
let free_size: usize = self.free.iter().map(|x| x.length).sum();
// Perform compaction if there is at least 1kb of free memory available
if free_size >= 1024 {
let mut last: Option<MemoryBlock> = None;
let mut free = Vec::new();
for block in self.free.iter() {
match last {
None => {
free.push(*block);
}
Some(last) => {
if last.offset + last.length == block.offset {
free.push(MemoryBlock {
offset: last.offset,
length: last.length + block.length,
});
}
}
}
last = Some(*block);
}
self.free = free;
}
}
/// Log entire memory as hexdump using the `trace` log level
pub fn dump(&self) {
let data = self.memory.data(self.store.as_ref().unwrap());
trace!("{:?}", data[..self.position].hex_dump());
}
/// Reset memory - clears free-list and live blocks and resets position
pub fn reset(&mut self) {
self.free.clear();
self.live_blocks.clear();
self.position = 1;
}
/// Get memory as a slice of bytes
pub fn data(&self) -> &[u8] {
self.memory.data(self.store.as_ref().unwrap())
}
/// Get memory as a mutable slice of bytes
pub fn data_mut(&mut self) -> &mut [u8] {
self.memory.data_mut(self.store.as_mut().unwrap())
}
/// Get bytes occupied by the provided memory handle
pub fn get(&self, handle: impl ToMemoryBlock) -> Result<&[u8], Error> {
let handle = handle.to_memory_block(self)?;
Ok(&self.memory.data(self.store.as_ref().unwrap())
[handle.offset..handle.offset + handle.length])
}
/// Get mutable bytes occupied by the provided memory handle
pub fn get_mut(&mut self, handle: impl ToMemoryBlock) -> Result<&mut [u8], Error> {
let handle = handle.to_memory_block(self)?;
Ok(&mut self.memory.data_mut(self.store.as_mut().unwrap())
[handle.offset..handle.offset + handle.length])
}
/// Get str occupied by the provided memory handle
pub fn get_str(&self, handle: impl ToMemoryBlock) -> Result<&str, Error> {
let handle = handle.to_memory_block(self)?;
Ok(std::str::from_utf8(
&self.memory.data(self.store.as_ref().unwrap())
[handle.offset..handle.offset + handle.length],
)?)
}
/// Get mutable str occupied by the provided memory handle
pub fn get_mut_str(&mut self, handle: impl ToMemoryBlock) -> Result<&mut str, Error> {
let handle = handle.to_memory_block(self)?;
Ok(std::str::from_utf8_mut(
&mut self.memory.data_mut(self.store.as_mut().unwrap())
[handle.offset..handle.offset + handle.length],
)?)
}
/// Pointer to the provided memory handle
pub fn ptr(&self, handle: impl ToMemoryBlock) -> Result<*mut u8, Error> {
let handle = handle.to_memory_block(self)?;
Ok(unsafe {
self.memory
.data_ptr(&self.store.as_ref().unwrap())
.add(handle.offset)
})
}
/// Get the length of the block starting at `offs`
pub fn block_length(&self, offs: usize) -> Option<usize> {
self.live_blocks.get(&offs).cloned()
}
/// Get the block at the specified offset
pub fn at_offset(&self, offset: usize) -> Option<MemoryBlock> {
let block_length = self.block_length(offset);
block_length.map(|length| MemoryBlock { offset, length })
}
}
#[derive(Clone, Copy)]
pub struct MemoryBlock {
pub offset: usize,
pub length: usize,
}
impl From<(usize, usize)> for MemoryBlock {
fn from(x: (usize, usize)) -> Self {
MemoryBlock {
offset: x.0,
length: x.1,
}
}
}
impl MemoryBlock {
pub fn new(offset: usize, length: usize) -> Self {
MemoryBlock { offset, length }
}
}

View File

@@ -18,177 +18,6 @@ macro_rules! args {
};
}
/// Get the input length
/// Params: none
/// Returns: i64 (length)
pub(crate) fn input_length(
caller: Caller<Internal>,
_input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &Internal = caller.data();
output[0] = Val::I64(data.input_length as i64);
Ok(())
}
/// Load a byte from input
/// Params: i64 (offset)
/// Returns: i32 (byte)
pub(crate) fn input_load_u8(
caller: Caller<Internal>,
input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &Internal = caller.data();
if data.input.is_null() {
return Ok(());
}
output[0] = unsafe { Val::I32(*data.input.add(input[0].unwrap_i64() as usize) as i32) };
Ok(())
}
/// Load an unsigned 64 bit integer from input
/// Params: i64 (offset)
/// Returns: i64 (int)
pub(crate) fn input_load_u64(
caller: Caller<Internal>,
input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &Internal = caller.data();
if data.input.is_null() {
return Ok(());
}
let offs = args!(input, 0, i64) as usize;
let slice = unsafe { std::slice::from_raw_parts(data.input.add(offs), 8) };
let byte = u64::from_ne_bytes(slice.try_into().unwrap());
output[0] = Val::I64(byte as i64);
Ok(())
}
/// Store a byte in memory
/// Params: i64 (offset), i32 (byte)
/// Returns: none
pub(crate) fn store_u8(
mut caller: Caller<Internal>,
input: &[Val],
_output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let (offset, byte) = args!(input, (0, i64), (1, i32));
data.memory_mut().store_u8(offset as usize, byte as u8)?;
Ok(())
}
/// Load a byte from memory
/// Params: i64 (offset)
/// Returns: i32 (byte)
pub(crate) fn load_u8(
caller: Caller<Internal>,
input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &Internal = caller.data();
let offset = args!(input, 0, i64) as usize;
let byte = data.memory().load_u8(offset)?;
output[0] = Val::I32(byte as i32);
Ok(())
}
/// Store an unsigned 64 bit integer in memory
/// Params: i64 (offset), i64 (int)
/// Returns: none
pub(crate) fn store_u64(
mut caller: Caller<Internal>,
input: &[Val],
_output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let (offset, b) = args!(input, (0, i64), (1, i64));
data.memory_mut().store_u64(offset as usize, b as u64)?;
Ok(())
}
/// Load an unsigned 64 bit integer from memory
/// Params: i64 (offset)
/// Returns: i64 (int)
pub(crate) fn load_u64(
caller: Caller<Internal>,
input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &Internal = caller.data();
let offset = args!(input, 0, i64) as usize;
let byte = data.memory().load_u64(offset)?;
output[0] = Val::I64(byte as i64);
Ok(())
}
/// Set output offset and length
/// Params: i64 (offset), i64 (length)
/// Returns: none
pub(crate) fn output_set(
mut caller: Caller<Internal>,
input: &[Val],
_output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let (offset, length) = args!(input, (0, i64), (1, i64));
data.output_offset = offset as usize;
data.output_length = length as usize;
Ok(())
}
/// Allocate bytes
/// Params: i64 (length)
/// Returns: i64 (offset)
pub(crate) fn alloc(
mut caller: Caller<Internal>,
input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let offs = data.memory_mut().alloc(input[0].unwrap_i64() as _)?;
output[0] = Val::I64(offs.offset as i64);
Ok(())
}
/// Free memory
/// Params: i64 (offset)
/// Returns: none
pub(crate) fn free(
mut caller: Caller<Internal>,
input: &[Val],
_output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let offset = args!(input, 0, i64) as usize;
data.memory_mut().free(offset);
Ok(())
}
/// Set the error message, this can be checked by the host program
/// Params: i64 (offset)
/// Returns: none
pub(crate) fn error_set(
mut caller: Caller<Internal>,
input: &[Val],
_output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let offset = args!(input, 0, i64) as usize;
if offset == 0 {
*data.last_error.borrow_mut() = None;
return Ok(());
}
let s = data.memory().get_str(offset)?;
data.set_error(s);
Ok(())
}
/// Get a configuration value
/// Params: i64 (offset)
/// Returns: i64 (offset)
@@ -199,21 +28,24 @@ pub(crate) fn config_get(
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let offset = args!(input, 0, i64) as usize;
let key = data.memory().get_str(offset)?;
let val = data.memory().manifest.as_ref().config.get(key);
let offset = args!(input, 0, i64) as u64;
let key = data.memory_read_str(offset)?;
let key = unsafe {
std::str::from_utf8_unchecked(std::slice::from_raw_parts(key.as_ptr(), key.len()))
};
let val = data.internal().manifest.as_ref().config.get(key);
let ptr = val.map(|x| (x.len(), x.as_ptr()));
let mem = match ptr {
Some((len, ptr)) => {
let bytes = unsafe { std::slice::from_raw_parts(ptr, len) };
data.memory_mut().alloc_bytes(bytes)?
data.memory_alloc_bytes(bytes)?
}
None => {
output[0] = Val::I64(0);
return Ok(());
}
};
output[0] = Val::I64(mem.offset as i64);
output[0] = Val::I64(mem as i64);
Ok(())
}
@@ -227,23 +59,24 @@ pub(crate) fn var_get(
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let offset = args!(input, 0, i64) as usize;
let key = data.memory().get_str(offset)?;
let val = data.vars.get(key);
let offset = args!(input, 0, i64) as u64;
let key = data.memory_read_str(offset)?;
let key = unsafe {
std::str::from_utf8_unchecked(std::slice::from_raw_parts(key.as_ptr(), key.len()))
};
let val = data.internal().vars.get(key);
let ptr = val.map(|x| (x.len(), x.as_ptr()));
let mem = match ptr {
Some((len, ptr)) => {
let bytes = unsafe { std::slice::from_raw_parts(ptr, len) };
data.memory_mut().alloc_bytes(bytes)?
data.memory_alloc_bytes(bytes)?
}
None => {
output[0] = Val::I64(0);
return Ok(());
}
};
output[0] = Val::I64(mem.offset as i64);
output[0] = Val::I64(mem as i64);
Ok(())
}
@@ -262,16 +95,16 @@ pub(crate) fn var_set(
size += v.len();
}
let voffset = args!(input, 1, i64) as usize;
let voffset = args!(input, 1, i64) as u64;
// If the store is larger than 100MB then stop adding things
if size > 1024 * 1024 * 100 && voffset != 0 {
return Err(Error::msg("Variable store is full"));
}
let key_offs = args!(input, 0, i64) as usize;
let key_offs = args!(input, 0, i64) as u64;
let key = {
let key = data.memory().get_str(key_offs)?;
let key = data.memory_read_str(key_offs)?;
let key_len = key.len();
let key_ptr = key.as_ptr();
unsafe { std::str::from_utf8_unchecked(std::slice::from_raw_parts(key_ptr, key_len)) }
@@ -283,10 +116,11 @@ pub(crate) fn var_set(
return Ok(());
}
let value = data.memory().get(voffset)?;
let vlen = data.memory_length(voffset);
let value = data.memory_read(voffset, vlen).to_vec();
// Insert the value from memory into the `vars` map
data.vars.insert(key.to_string(), value.to_vec());
data.vars.insert(key.to_string(), value);
Ok(())
}
@@ -312,18 +146,19 @@ pub(crate) fn http_request(
{
use std::io::Read;
let data: &mut Internal = caller.data_mut();
let http_req_offset = args!(input, 0, i64) as usize;
let http_req_offset = args!(input, 0, i64) as u64;
let http_req_len = data.memory_length(http_req_offset);
let req: extism_manifest::HttpRequest =
serde_json::from_slice(data.memory().get(http_req_offset)?)?;
serde_json::from_slice(data.memory_read(http_req_offset, http_req_len))?;
let body_offset = args!(input, 1, i64) as usize;
let body_offset = args!(input, 1, i64) as u64;
let url = match url::Url::parse(&req.url) {
Ok(u) => u,
Err(e) => return Err(Error::msg(format!("Invalid URL: {e:?}"))),
};
let allowed_hosts = &data.memory().manifest.as_ref().allowed_hosts;
let allowed_hosts = &data.internal().manifest.as_ref().allowed_hosts;
let host_str = url.host_str().unwrap_or_default();
let host_matches = if let Some(allowed_hosts) = allowed_hosts {
allowed_hosts.iter().any(|url| {
@@ -352,7 +187,8 @@ pub(crate) fn http_request(
}
let res = if body_offset > 0 {
let buf = data.memory().get(body_offset)?;
let len = data.memory_length(body_offset);
let buf = data.memory_read(body_offset, len);
r.send_bytes(buf)
} else {
r.call()
@@ -364,6 +200,7 @@ pub(crate) fn http_request(
Some(res.into_reader())
}
Err(e) => {
log::error!("Unable to make HTTP request: {:?}", e);
if let Some(res) = e.into_response() {
data.http_status = res.status();
Some(res.into_reader())
@@ -379,9 +216,8 @@ pub(crate) fn http_request(
.take(1024 * 1024 * 50) // TODO: make this limit configurable
.read_to_end(&mut buf)?;
let mem = data.memory_mut().alloc_bytes(buf)?;
output[0] = Val::I64(mem.offset as i64);
let mem = data.memory_alloc_bytes(buf)?;
output[0] = Val::I64(mem as i64);
} else {
output[0] = Val::I64(0);
}
@@ -403,39 +239,17 @@ pub(crate) fn http_status_code(
Ok(())
}
/// Get the length of an allocated block given the offset
/// Params: i64 (offset)
/// Returns: i64 (length or 0)
pub(crate) fn length(
mut caller: Caller<Internal>,
input: &[Val],
output: &mut [Val],
) -> Result<(), Error> {
let data: &mut Internal = caller.data_mut();
let offset = args!(input, 0, i64) as usize;
if offset == 0 {
output[0] = Val::I64(0);
return Ok(());
}
let length = match data.memory().block_length(offset) {
Some(x) => x,
None => return Err(Error::msg("Unable to find length for offset")),
};
output[0] = Val::I64(length as i64);
Ok(())
}
pub fn log(
level: log::Level,
caller: Caller<Internal>,
mut caller: Caller<Internal>,
input: &[Val],
_output: &mut [Val],
) -> Result<(), Error> {
let data: &Internal = caller.data();
let offset = args!(input, 0, i64) as usize;
let buf = data.memory().get(offset)?;
let data: &mut Internal = caller.data_mut();
let offset = args!(input, 0, i64) as u64;
let buf = data.memory_read_str(offset);
match std::str::from_utf8(buf) {
match buf {
Ok(buf) => log::log!(level, "{}", buf),
Err(_) => log::log!(level, "{:?}", buf),
}

View File

@@ -9,17 +9,16 @@ pub struct Plugin {
/// Used to define functions and create new instances
pub linker: Linker<Internal>,
pub store: Store<Internal>,
/// Instance provides the ability to call functions in a module
pub instance: Instance,
pub instance: Option<Instance>,
pub instance_pre: InstancePre<Internal>,
/// Keep track of the number of times we're instantiated, this exists
/// to avoid issues with memory piling up since `Instance`s are only
/// actually cleaned up along with a `Store`
pub instantiations: usize,
/// Handles interactions with WASM memory
pub memory: std::cell::UnsafeCell<PluginMemory>,
instantiations: usize,
/// The ID used to identify this plugin with the `Timer`
pub timer_id: uuid::Uuid,
@@ -27,18 +26,30 @@ pub struct Plugin {
/// A handle used to cancel execution of a plugin
pub(crate) cancel_handle: sdk::ExtismCancelHandle,
/// Runtime determines any initialization and cleanup functions needed
/// Runtime determines any initialization functions needed
/// to run a module
pub(crate) runtime: Option<Runtime>,
}
impl InternalExt for Plugin {
fn memory(&self) -> &PluginMemory {
unsafe { &*self.memory.get() }
fn store(&self) -> &Store<Internal> {
&self.store
}
fn memory_mut(&mut self) -> &mut PluginMemory {
self.memory.get_mut()
fn store_mut(&mut self) -> &mut Store<Internal> {
&mut self.store
}
fn linker(&self) -> &Linker<Internal> {
&self.linker
}
fn linker_mut(&mut self) -> &mut Linker<Internal> {
&mut self.linker
}
fn linker_and_store(&mut self) -> (&mut Linker<Internal>, &mut Store<Internal>) {
(&mut self.linker, &mut self.store)
}
}
@@ -55,6 +66,59 @@ fn profiling_strategy() -> ProfilingStrategy {
}
}
fn calculate_available_memory(
available_pages: &mut Option<u32>,
modules: &BTreeMap<String, Module>,
) -> anyhow::Result<()> {
let available_pages = match available_pages {
Some(p) => p,
None => return Ok(()),
};
let max_pages = *available_pages;
let mut fail_memory_check = false;
let mut total_memory_needed = 0;
for (name, module) in modules.iter() {
if name == "env" {
continue;
}
let mut memories = 0;
for export in module.exports() {
if let Some(memory) = export.ty().memory() {
memories += 1;
let memory_max = memory.maximum();
match memory_max {
None => anyhow::bail!("Unbounded memory in module {name}, when `memory.max_pages` is set in the manifest all modules \
must have a maximum bound set on an exported memory"),
Some(m) => {
total_memory_needed += m;
if !fail_memory_check {
continue;
}
*available_pages = available_pages.saturating_sub(m as u32);
if *available_pages == 0 {
fail_memory_check = true;
}
}
}
}
}
if memories == 0 {
anyhow::bail!("No memory exported from module {name}, when `memory.max_pages` is set in the manifest all modules must \
have a maximum bound set on an exported memory");
}
}
if fail_memory_check {
anyhow::bail!("Not enough memory configured to run the provided plugin, `memory.max_pages` is set to {max_pages} in the manifest \
but {total_memory_needed} pages are needed by the plugin");
}
Ok(())
}
impl Plugin {
/// Create a new plugin from the given WASM code
pub fn new<'a>(
@@ -68,20 +132,28 @@ impl Plugin {
Config::new()
.epoch_interruption(true)
.debug_info(std::env::var("EXTISM_DEBUG").is_ok())
.profiler(profiling_strategy()),
.profiler(profiling_strategy())
.cache_config_load_default()?,
)?;
let mut imports = imports.into_iter();
let (manifest, modules) = Manifest::new(&engine, wasm.as_ref())?;
let mut store = Store::new(&engine, Internal::new(&manifest, with_wasi)?);
store.epoch_deadline_callback(|_internal| Err(Error::msg("timeout")));
// Create memory
let memory = Memory::new(
&mut store,
MemoryType::new(4, manifest.as_ref().memory.max_pages),
)?;
let mut memory = PluginMemory::new(store, memory, manifest);
// Calculate how much memory is available based on the value of `max_pages` and the exported
// memory of the modules. An error will be returned if a module doesn't have an exported memory
// or there is no maximum set for a module's exported memory.
let mut available_pages = manifest.as_ref().memory.max_pages;
calculate_available_memory(&mut available_pages, &modules)?;
log::trace!("Available pages: {available_pages:?}");
let mut store = Store::new(
&engine,
Internal::new(manifest, with_wasi, available_pages)?,
);
store.epoch_deadline_callback(|_internal| Ok(wasmtime::UpdateDeadline::Continue(1)));
if available_pages.is_some() {
store.limiter(|internal| internal.memory_limiter.as_mut().unwrap());
}
let mut linker = Linker::new(&engine);
linker.allow_shadowing(true);
@@ -119,7 +191,10 @@ impl Plugin {
}
// Add builtins
for (_name, module) in modules.iter() {
for (name, module) in modules.iter() {
if name != main_name {
linker.module(&mut store, name, module)?;
}
for import in module.imports() {
let module_name = import.module();
let name = import.name();
@@ -127,249 +202,242 @@ impl Plugin {
if module_name == EXPORT_MODULE_NAME {
define_funcs!(name, {
alloc(I64) -> I64;
free(I64);
load_u8(I64) -> I32;
load_u64(I64) -> I64;
store_u8(I64, I32);
store_u64(I64, I64);
input_length() -> I64;
input_load_u8(I64) -> I32;
input_load_u64(I64) -> I64;
output_set(I64, I64);
error_set(I64);
config_get(I64) -> I64;
var_get(I64) -> I64;
var_set(I64, I64);
http_request(I64, I64) -> I64;
http_status_code() -> I32;
length(I64) -> I64;
log_warn(I64);
log_info(I64);
log_debug(I64);
log_error(I64);
});
for f in &mut imports {
let name = f.name().to_string();
let ns = f.namespace().unwrap_or(EXPORT_MODULE_NAME);
linker.func_new(ns, &name, f.ty().clone(), unsafe {
&*std::sync::Arc::as_ptr(&f.f)
})?;
}
}
}
}
// Add modules to linker
for (name, module) in modules.iter() {
if name != main_name {
linker.module(&mut memory.store_mut(), name, module)?;
}
for f in &mut imports {
let name = f.name().to_string();
let ns = f.namespace().unwrap_or(EXPORT_MODULE_NAME);
linker.func_new(ns, &name, f.ty().clone(), unsafe {
&*std::sync::Arc::as_ptr(&f.f)
})?;
}
let instance = linker.instantiate(&mut memory.store_mut(), main)?;
let instance_pre = linker.instantiate_pre(&main)?;
let timer_id = uuid::Uuid::new_v4();
let mut plugin = Plugin {
modules,
linker,
memory: std::cell::UnsafeCell::new(memory),
instance,
instantiations: 1,
instance: None,
instance_pre,
store,
runtime: None,
timer_id,
cancel_handle: sdk::ExtismCancelHandle {
id: timer_id,
epoch_timer_tx: None,
},
instantiations: 0,
};
// Make sure `Internal::memory` is initialized
plugin.internal_mut().memory = plugin.memory.get();
// Then detect runtime before returning the new plugin
plugin.detect_runtime();
plugin.internal_mut().store = &mut plugin.store;
plugin.internal_mut().linker = &mut plugin.linker;
Ok(plugin)
}
pub(crate) fn reset_store(&mut self) -> Result<(), Error> {
self.instance = None;
if self.instantiations > 5 {
let (main_name, main) = self
.modules
.get("main")
.map(|x| ("main", x))
.unwrap_or_else(|| {
let entry = self.modules.iter().last().unwrap();
(entry.0.as_str(), entry.1)
});
let engine = self.store.engine().clone();
let internal = self.internal();
self.store = Store::new(
&engine,
Internal::new(
internal.manifest.clone(),
internal.wasi.is_some(),
internal.available_pages,
)?,
);
self.store
.epoch_deadline_callback(|_internal| Ok(UpdateDeadline::Continue(1)));
if self.internal().available_pages.is_some() {
self.store
.limiter(|internal| internal.memory_limiter.as_mut().unwrap());
}
for (name, module) in self.modules.iter() {
if name != main_name {
self.linker.module(&mut self.store, name, module)?;
}
}
self.instantiations = 0;
self.instance_pre = self.linker.instantiate_pre(&main)?;
let store = &mut self.store as *mut _;
let linker = &mut self.linker as *mut _;
let internal = self.internal_mut();
internal.store = store;
internal.linker = linker;
}
Ok(())
}
pub(crate) fn instantiate(&mut self) -> Result<(), Error> {
self.instance = Some(self.instance_pre.instantiate(&mut self.store)?);
self.instantiations += 1;
if let Some(limiter) = &mut self.internal_mut().memory_limiter {
limiter.reset();
}
self.detect_runtime();
self.initialize_runtime()?;
Ok(())
}
/// Get a function by name
pub fn get_func(&mut self, function: impl AsRef<str>) -> Option<Func> {
self.instance
.get_func(&mut self.memory.get_mut().store_mut(), function.as_ref())
}
if let None = &self.instance {
if let Err(e) = self.instantiate() {
error!("Unable to instantiate: {e}");
return None;
}
}
// A convenience method to set the plugin error and return a value
pub fn error<E>(&self, e: impl std::fmt::Debug, x: E) -> E {
self.store().data().set_error(e);
x
if let Some(instance) = &mut self.instance {
instance.get_func(&mut self.store, function.as_ref())
} else {
None
}
}
/// Store input in memory and initialize `Internal` pointer
pub fn set_input(&mut self, input: *const u8, mut len: usize) {
pub(crate) fn set_input(&mut self, input: *const u8, mut len: usize) -> Result<(), Error> {
if input.is_null() {
len = 0;
}
let ptr = self.memory.get();
let internal = self.internal_mut();
internal.input = input;
internal.input_length = len;
internal.memory = ptr
}
/// Dump memory using trace! logging
pub fn dump_memory(&self) {
self.memory().dump();
}
/// Create a new instance from the same modules
pub fn reinstantiate(&mut self) -> Result<(), Error> {
let (main_name, main) = self
.modules
.get("main")
.map(|x| ("main", x))
.unwrap_or_else(|| {
let entry = self.modules.iter().last().unwrap();
(entry.0.as_str(), entry.1)
});
// Avoid running into resource limits, after 5 instantiations reset the store. This will
// release any old `Instance` objects
if self.instantiations > 5 {
self.memory.get_mut().reinstantiate()?;
// Get the `main` module, or the last one if `main` doesn't exist
for (name, module) in self.modules.iter() {
if name != main_name {
self.linker
.module(&mut self.memory.get_mut().store_mut(), name, module)?;
}
}
self.instantiations = 0;
{
let store = &mut self.store as *mut _;
let linker = &mut self.linker as *mut _;
let internal = self.internal_mut();
internal.store = store;
internal.linker = linker;
}
if len > 0 {
let bytes = unsafe { std::slice::from_raw_parts(input, len) };
trace!("Input size: {}", bytes.len());
if let Some(f) = self.linker.get(&mut self.store, "env", "extism_reset") {
f.into_func().unwrap().call(&mut self.store, &[], &mut [])?;
} else {
error!("Call to extism_reset failed");
}
let offs = self.memory_alloc_bytes(bytes)?;
if let Some(f) = self.linker.get(&mut self.store, "env", "extism_input_set") {
f.into_func().unwrap().call(
&mut self.store,
&[Val::I64(offs as i64), Val::I64(len as i64)],
&mut [],
)?;
}
}
let instance = self
.linker
.instantiate(&mut self.memory.get_mut().store_mut(), &main)?;
self.instance = instance;
self.detect_runtime();
self.instantiations += 1;
Ok(())
}
/// Determine if wasi is enabled
pub fn has_wasi(&self) -> bool {
self.memory().store().data().wasi.is_some()
self.internal().wasi.is_some()
}
fn detect_runtime(&mut self) {
// Check for Haskell runtime initialization functions
// Initialize Haskell runtime if `hs_init` and `hs_exit` are present,
// Initialize Haskell runtime if `hs_init` is present,
// by calling the `hs_init` export
if let Some(init) = self.get_func("hs_init") {
if let Some(cleanup) = self.get_func("hs_exit") {
if init
.typed::<(i32, i32), ()>(&self.memory().store())
.is_err()
{
let reactor_init = if let Some(init) = self.get_func("_initialize") {
if init.typed::<(), ()>(&self.store()).is_err() {
trace!(
"hs_init function found with type {:?}",
init.ty(&self.memory().store())
"_initialize function found with type {:?}",
init.ty(self.store())
);
None
} else {
trace!("WASI reactor module detected");
Some(init)
}
self.runtime = Some(Runtime::Haskell { init, cleanup });
}
} else {
None
};
self.runtime = Some(Runtime::Haskell { init, reactor_init });
return;
}
// Check for `__wasm__call_ctors` and `__wasm_call_dtors`, this is used by WASI to
// Check for `__wasm_call_ctors` or `_initialize`, this is used by WASI to
// initialize certain interfaces.
if self.has_wasi() {
if let Some(init) = self.get_func("__wasm_call_ctors") {
if init.typed::<(), ()>(&self.memory().store()).is_err() {
trace!(
"__wasm_call_ctors function found with type {:?}",
init.ty(&self.memory().store())
);
return;
}
trace!("WASI runtime detected");
if let Some(cleanup) = self.get_func("__wasm_call_dtors") {
if cleanup.typed::<(), ()>(&self.memory().store()).is_err() {
trace!(
"__wasm_call_dtors function found with type {:?}",
cleanup.ty(&self.memory().store())
);
return;
}
self.runtime = Some(Runtime::Wasi {
init,
cleanup: Some(cleanup),
});
return;
}
self.runtime = Some(Runtime::Wasi {
init,
cleanup: None,
});
let init = if let Some(init) = self.get_func("__wasm_call_ctors") {
if init.typed::<(), ()>(&self.store()).is_err() {
trace!(
"__wasm_call_ctors function found with type {:?}",
init.ty(self.store())
);
return;
}
trace!("WASI runtime detected");
init
} else if let Some(init) = self.get_func("_initialize") {
if init.typed::<(), ()>(&self.store()).is_err() {
trace!(
"_initialize function found with type {:?}",
init.ty(self.store())
);
return;
}
trace!("Reactor module detected");
init
} else {
return;
}
};
self.runtime = Some(Runtime::Wasi { init });
trace!("No runtime detected");
}
pub(crate) fn initialize_runtime(&mut self) -> Result<(), Error> {
let mut store = &mut self.store;
if let Some(runtime) = &self.runtime {
trace!("Plugin::initialize_runtime");
match runtime {
Runtime::Haskell { init, cleanup: _ } => {
let mut results =
vec![Val::null(); init.ty(&self.memory().store()).results().len()];
Runtime::Haskell { init, reactor_init } => {
if let Some(reactor_init) = reactor_init {
reactor_init.call(&mut store, &[], &mut [])?;
}
let mut results = vec![Val::null(); init.ty(&store).results().len()];
init.call(
&mut self.memory.get_mut().store_mut(),
&mut store,
&[Val::I32(0), Val::I32(0)],
results.as_mut_slice(),
)?;
debug!("Initialized Haskell language runtime");
}
Runtime::Wasi { init, cleanup: _ } => {
debug!("Calling __wasm_call_ctors");
init.call(&mut self.memory.get_mut().store_mut(), &[], &mut [])?;
}
}
}
Ok(())
}
#[inline(always)]
pub(crate) fn cleanup_runtime(&mut self) -> Result<(), Error> {
if let Some(runtime) = self.runtime.clone() {
trace!("Plugin::cleanup_runtime");
match runtime {
Runtime::Wasi {
init: _,
cleanup: Some(cleanup),
} => {
debug!("Calling __wasm_call_dtors");
cleanup.call(&mut self.memory_mut().store_mut(), &[], &mut [])?;
}
Runtime::Wasi {
init: _,
cleanup: None,
} => (),
// Cleanup Haskell runtime if `hs_exit` and `hs_exit` are present,
// by calling the `hs_exit` export
Runtime::Haskell { init: _, cleanup } => {
let mut results =
vec![Val::null(); cleanup.ty(&self.memory().store()).results().len()];
cleanup.call(
&mut self.memory_mut().store_mut(),
&[],
results.as_mut_slice(),
)?;
debug!("Cleaned up Haskell language runtime");
Runtime::Wasi { init } => {
init.call(&mut store, &[], &mut [])?;
debug!("Initialied WASI runtime");
}
}
}
@@ -384,14 +452,16 @@ impl Plugin {
tx: &std::sync::mpsc::SyncSender<TimerAction>,
) -> Result<(), Error> {
let duration = self
.memory()
.internal()
.manifest
.as_ref()
.timeout_ms
.map(std::time::Duration::from_millis);
self.cancel_handle.epoch_timer_tx = Some(tx.clone());
self.memory_mut().store_mut().set_epoch_deadline(1);
let engine: Engine = self.memory().store().engine().clone();
self.store_mut().set_epoch_deadline(1);
self.store
.epoch_deadline_callback(|_internal| Err(Error::msg("timeout")));
let engine: Engine = self.store().engine().clone();
tx.send(TimerAction::Start {
id: self.timer_id,
duration,
@@ -405,6 +475,8 @@ impl Plugin {
if let Some(tx) = &self.cancel_handle.epoch_timer_tx {
tx.send(TimerAction::Stop { id: self.timer_id })?;
}
self.store
.epoch_deadline_callback(|_internal| Ok(wasmtime::UpdateDeadline::Continue(1)));
Ok(())
}
}
@@ -412,6 +484,11 @@ impl Plugin {
// Enumerates the supported PDK language runtimes
#[derive(Clone)]
pub(crate) enum Runtime {
Haskell { init: Func, cleanup: Func },
Wasi { init: Func, cleanup: Option<Func> },
Haskell {
init: Func,
reactor_init: Option<Func>,
},
Wasi {
init: Func,
},
}

View File

@@ -3,6 +3,7 @@ use crate::*;
// PluginRef is used to access a plugin from a context-scoped plugin registry
pub struct PluginRef<'a> {
pub id: PluginIndex,
running: bool,
pub(crate) epoch_timer_tx: std::sync::mpsc::SyncSender<TimerAction>,
plugin: *mut Plugin,
_t: std::marker::PhantomData<&'a ()>,
@@ -10,23 +11,25 @@ pub struct PluginRef<'a> {
impl<'a> PluginRef<'a> {
/// Initialize the plugin for a new call
///
/// - Resets memory offsets
/// - Updates `input` pointer
pub fn init(mut self, data: *const u8, data_len: usize) -> Self {
trace!("PluginRef::init: {}", self.id,);
let plugin = self.as_mut();
plugin.memory_mut().reset();
if plugin.has_wasi() || plugin.runtime.is_some() {
if let Err(e) = plugin.reinstantiate() {
error!("Failed to reinstantiate: {e:?}");
plugin
.internal()
.set_error(format!("Failed to reinstantiate: {e:?}"));
return self;
pub(crate) fn start_call(mut self, is_start: bool) -> Self {
trace!("PluginRef::start_call: {}", self.id,);
let plugin = unsafe { &mut *self.plugin };
if is_start {
if let Err(e) = plugin.reset_store() {
error!("Call to Plugin::reset_store failed: {e:?}");
}
}
plugin.set_input(data, data_len);
if plugin.instance.is_none() {
trace!("Plugin::instance is none, instantiating");
if let Err(e) = plugin.instantiate() {
error!("Plugin::instantiate failed: {e:?}");
plugin.error(e, ());
}
}
self.running = true;
self
}
@@ -45,13 +48,13 @@ impl<'a> PluginRef<'a> {
return ctx.error(format!("Plugin does not exist: {plugin_id}"), None);
};
let plugin = unsafe { &mut *plugin };
if clear_error {
trace!("Clearing context error");
ctx.error = None;
trace!("Clearing plugin error: {plugin_id}");
unsafe {
(&*plugin).internal().clear_error();
}
plugin.clear_error();
}
Some(PluginRef {
@@ -59,6 +62,7 @@ impl<'a> PluginRef<'a> {
plugin,
epoch_timer_tx,
_t: std::marker::PhantomData,
running: false,
})
}
}
@@ -78,6 +82,14 @@ impl<'a> AsMut<Plugin> for PluginRef<'a> {
impl<'a> Drop for PluginRef<'a> {
fn drop(&mut self) {
trace!("Dropping PluginRef {}", self.id);
// Cleanup?
if self.running {
let plugin = self.as_mut();
// Stop timer
if let Err(e) = plugin.stop_timer() {
let id = plugin.timer_id;
error!("Failed to stop timeout manager for {id}: {e:?}");
}
}
}
}

View File

@@ -99,7 +99,7 @@ pub unsafe extern "C" fn extism_current_plugin_memory(plugin: *mut Internal) ->
}
let plugin = &mut *plugin;
plugin.memory_mut().data_mut().as_mut_ptr()
plugin.memory_ptr()
}
/// Allocate a memory block in the currently running plugin
@@ -111,16 +111,7 @@ pub unsafe extern "C" fn extism_current_plugin_memory_alloc(plugin: *mut Interna
}
let plugin = &mut *plugin;
let mem = match plugin.memory_mut().alloc(n as usize) {
Ok(x) => x,
Err(e) => {
plugin.set_error(e);
return 0;
}
};
mem.offset as u64
plugin.memory_alloc(n as u64).unwrap_or_default()
}
/// Get the length of an allocated block
@@ -135,11 +126,7 @@ pub unsafe extern "C" fn extism_current_plugin_memory_length(
}
let plugin = &mut *plugin;
match plugin.memory().block_length(n as usize) {
Some(x) => x as Size,
None => 0,
}
plugin.memory_length(n)
}
/// Free an allocated memory block
@@ -151,7 +138,7 @@ pub unsafe extern "C" fn extism_current_plugin_memory_free(plugin: *mut Internal
}
let plugin = &mut *plugin;
plugin.memory_mut().free(ptr as usize);
plugin.memory_free(ptr);
}
/// Create a new host function
@@ -436,21 +423,21 @@ pub unsafe extern "C" fn extism_plugin_config(
}
};
let wasi = &mut plugin.memory.get_mut().store_mut().data_mut().wasi;
let wasi = &mut plugin.internal_mut().wasi;
if let Some(Wasi { ctx, .. }) = wasi {
for (k, v) in json.iter() {
match v {
Some(v) => {
let _ = ctx.push_env(&k, &v);
let _ = ctx.push_env(k, v);
}
None => {
let _ = ctx.push_env(&k, "");
let _ = ctx.push_env(k, "");
}
}
}
}
let config = &mut plugin.memory.get_mut().manifest.as_mut().config;
let config = &mut plugin.internal_mut().manifest.as_mut().config;
for (k, v) in json.into_iter() {
match v {
Some(v) => {
@@ -508,41 +495,28 @@ pub unsafe extern "C" fn extism_plugin_call(
) -> i32 {
let ctx = &mut *ctx;
// Get function name
let name = std::ffi::CStr::from_ptr(func_name);
let name = match name.to_str() {
Ok(name) => name,
Err(e) => return ctx.error(e, -1),
};
let is_start = name == "_start";
// Get a `PluginRef` and call `init` to set up the plugin input and memory, this is only
// needed before a new call
let mut plugin_ref = match PluginRef::new(ctx, plugin_id, true) {
None => return -1,
Some(p) => p.init(data, data_len as usize),
Some(p) => p.start_call(is_start),
};
let tx = plugin_ref.epoch_timer_tx.clone();
let plugin = plugin_ref.as_mut();
if plugin.internal().last_error.borrow().is_some() {
return -1;
}
// Find function
let name = std::ffi::CStr::from_ptr(func_name);
let name = match name.to_str() {
Ok(name) => name,
Err(e) => return plugin.error(e, -1),
};
let is_start = name == "_start";
let func = match plugin.get_func(name) {
Some(x) => x,
None => return plugin.error(format!("Function not found: {name}"), -1),
};
// Start timer
if let Err(e) = plugin.start_timer(&tx) {
let id = plugin.timer_id;
return plugin.error(
format!("Unable to start timeout manager for {id}: {e:?}"),
-1,
);
}
// Check the number of results, reject functions with more than 1 result
let n_results = func.ty(plugin.store()).results().len();
if n_results > 1 {
@@ -552,40 +526,29 @@ pub unsafe extern "C" fn extism_plugin_call(
);
}
// Initialize runtime
if !is_start {
if let Err(e) = plugin.initialize_runtime() {
return plugin.error(format!("Failed to initialize runtime: {e:?}"), -1);
}
if let Err(e) = plugin.set_input(data, data_len as usize) {
return plugin.error(e, -1);
}
if plugin.has_error() {
return -1;
}
// Start timer, this will be stopped when PluginRef goes out of scope
if let Err(e) = plugin.start_timer(&tx) {
return plugin.error(e, -1);
}
debug!("Calling function: {name} in plugin {plugin_id}");
// Call the function
let mut results = vec![wasmtime::Val::null(); n_results];
let res = func.call(&mut plugin.store_mut(), &[], results.as_mut_slice());
plugin.dump_memory();
// Cleanup runtime
if !is_start {
if let Err(e) = plugin.cleanup_runtime() {
return plugin.error(format!("Failed to cleanup runtime: {e:?}"), -1);
}
}
// Stop timer
if let Err(e) = plugin.stop_timer() {
let id = plugin.timer_id;
return plugin.error(
format!("Failed to stop timeout manager for {id}: {e:?}"),
-1,
);
}
let res = func.call(plugin.store_mut(), &[], results.as_mut_slice());
match res {
Ok(()) => (),
Err(e) => {
plugin.store.set_epoch_deadline(1);
if let Some(exit) = e.downcast_ref::<wasmtime_wasi::I32Exit>() {
trace!("WASI return code: {}", exit.0);
if exit.0 != 0 {
@@ -635,20 +598,27 @@ pub unsafe extern "C" fn extism_error(ctx: *mut Context, plugin: PluginIndex) ->
return get_context_error(ctx);
}
let plugin_ref = match PluginRef::new(ctx, plugin, false) {
let mut plugin_ref = match PluginRef::new(ctx, plugin, false) {
None => return std::ptr::null(),
Some(p) => p,
};
let plugin = plugin_ref.as_ref();
let err = plugin.internal().last_error.borrow();
match err.as_ref() {
Some(e) => e.as_ptr() as *const _,
None => {
trace!("Error is NULL");
std::ptr::null()
}
let plugin = plugin_ref.as_mut();
let output = &mut [Val::I64(0)];
if let Some(f) = plugin
.linker
.get(&mut plugin.store, "env", "extism_error_get")
{
f.into_func()
.unwrap()
.call(&mut plugin.store, &[], output)
.unwrap();
}
if output[0].unwrap_i64() == 0 {
trace!("Error is NULL");
return std::ptr::null();
}
plugin.memory_ptr().add(output[0].unwrap_i64() as usize) as *const _
}
/// Get the length of a plugin's output data
@@ -660,18 +630,25 @@ pub unsafe extern "C" fn extism_plugin_output_length(
trace!("Call to extism_plugin_output_length for plugin {plugin}");
let ctx = &mut *ctx;
let plugin_ref = match PluginRef::new(ctx, plugin, true) {
let mut plugin_ref = match PluginRef::new(ctx, plugin, true) {
None => return 0,
Some(p) => p,
};
let plugin = plugin_ref.as_ref();
let len = plugin.internal().output_length as Size;
let plugin = plugin_ref.as_mut();
let out = &mut [Val::I64(0)];
let _ = plugin
.linker
.get(&mut plugin.store, "env", "extism_output_length")
.unwrap()
.into_func()
.unwrap()
.call(&mut plugin.store_mut(), &[], out);
let len = out[0].unwrap_i64() as Size;
trace!("Output length: {len}");
len
}
/// Get the length of a plugin's output data
/// Get a pointer to the output data
#[no_mangle]
pub unsafe extern "C" fn extism_plugin_output_data(
ctx: *mut Context,
@@ -680,20 +657,26 @@ pub unsafe extern "C" fn extism_plugin_output_data(
trace!("Call to extism_plugin_output_data for plugin {plugin}");
let ctx = &mut *ctx;
let plugin_ref = match PluginRef::new(ctx, plugin, true) {
let mut plugin_ref = match PluginRef::new(ctx, plugin, true) {
None => return std::ptr::null(),
Some(p) => p,
};
let plugin = plugin_ref.as_ref();
let internal = plugin.internal();
let plugin = plugin_ref.as_mut();
let ptr = plugin.memory_ptr();
let out = &mut [Val::I64(0)];
let mut store = &mut *(plugin.store_mut() as *mut Store<_>);
plugin
.memory()
.ptr(MemoryBlock::new(
internal.output_offset,
internal.output_length,
))
.map(|x| x as *const _)
.unwrap_or(std::ptr::null())
.linker
.get(&mut store, "env", "extism_output_offset")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[], out)
.unwrap();
let offs = out[0].unwrap_i64() as usize;
trace!("Output offset: {}", offs);
ptr.add(offs)
}
/// Set log file and level

View File

@@ -1,6 +1,6 @@
[package]
name = "extism"
version = "0.3.0"
version = "0.5.5"
edition = "2021"
authors = ["The Extism Authors", "oss@extism.org"]
license = "BSD-3-Clause"
@@ -9,8 +9,8 @@ repository = "https://github.com/extism/extism"
description = "Extism Host SDK for Rust"
[dependencies]
extism-manifest = { version = "0.3.0", path = "../manifest" }
extism-runtime = { version = "0.4.0", path = "../runtime"}
extism-manifest = { version = "0.5.0", path = "../manifest" }
extism-runtime = { version = "0.5.5", path = "../runtime"}
serde_json = "1"
log = "0.4"
anyhow = "1"

View File

@@ -1,45 +1,260 @@
/* automatically generated by rust-bindgen 0.60.1 */
/* automatically generated by rust-bindgen 0.65.1 */
pub type __uint8_t = ::std::os::raw::c_uchar;
pub type __int32_t = ::std::os::raw::c_int;
pub type __uint64_t = ::std::os::raw::c_ulong;
#[doc = " Signed 32 bit integer."]
pub const ExtismValType_I32: ExtismValType = 0;
#[doc = " Signed 64 bit integer."]
pub const ExtismValType_I64: ExtismValType = 1;
#[doc = " Floating point 32 bit integer."]
pub const ExtismValType_F32: ExtismValType = 2;
#[doc = " Floating point 64 bit integer."]
pub const ExtismValType_F64: ExtismValType = 3;
#[doc = " A 128 bit number."]
pub const ExtismValType_V128: ExtismValType = 4;
#[doc = " A reference to a Wasm function."]
pub const ExtismValType_FuncRef: ExtismValType = 5;
#[doc = " A reference to opaque data in the Wasm instance."]
pub const ExtismValType_ExternRef: ExtismValType = 6;
#[doc = " A list of all possible value types in WebAssembly."]
pub type ExtismValType = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtismContext {
_unused: [u8; 0],
}
pub type ExtismPlugin = i32;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtismCancelHandle {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtismFunction {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtismCurrentPlugin {
_unused: [u8; 0],
}
pub type ExtismSize = u64;
#[doc = " A union type for host function argument/return values"]
#[repr(C)]
#[derive(Copy, Clone)]
pub union ExtismValUnion {
pub i32_: i32,
pub i64_: i64,
pub f32_: f32,
pub f64_: f64,
}
#[test]
fn bindgen_test_layout_ExtismValUnion() {
const UNINIT: ::std::mem::MaybeUninit<ExtismValUnion> = ::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<ExtismValUnion>(),
8usize,
concat!("Size of: ", stringify!(ExtismValUnion))
);
assert_eq!(
::std::mem::align_of::<ExtismValUnion>(),
8usize,
concat!("Alignment of ", stringify!(ExtismValUnion))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).i32_) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(ExtismValUnion),
"::",
stringify!(i32_)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).i64_) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(ExtismValUnion),
"::",
stringify!(i64_)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).f32_) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(ExtismValUnion),
"::",
stringify!(f32_)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).f64_) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(ExtismValUnion),
"::",
stringify!(f64_)
)
);
}
#[doc = " `ExtismVal` holds the type and value of a function argument/return"]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ExtismVal {
pub t: ExtismValType,
pub v: ExtismValUnion,
}
#[test]
fn bindgen_test_layout_ExtismVal() {
const UNINIT: ::std::mem::MaybeUninit<ExtismVal> = ::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<ExtismVal>(),
16usize,
concat!("Size of: ", stringify!(ExtismVal))
);
assert_eq!(
::std::mem::align_of::<ExtismVal>(),
8usize,
concat!("Alignment of ", stringify!(ExtismVal))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).t) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(ExtismVal),
"::",
stringify!(t)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).v) as usize - ptr as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(ExtismVal),
"::",
stringify!(v)
)
);
}
#[doc = " Host function signature"]
pub type ExtismFunctionType = ::std::option::Option<
unsafe extern "C" fn(
plugin: *mut ExtismCurrentPlugin,
inputs: *const ExtismVal,
n_inputs: ExtismSize,
outputs: *mut ExtismVal,
n_outputs: ExtismSize,
data: *mut ::std::os::raw::c_void,
),
>;
pub type ExtismPlugin = i32;
extern "C" {
#[doc = " Create a new context"]
pub fn extism_context_new() -> *mut ExtismContext;
}
extern "C" {
#[doc = " Free a context"]
pub fn extism_context_free(ctx: *mut ExtismContext);
}
extern "C" {
#[doc = " Returns a pointer to the memory of the currently running plugin\n NOTE: this should only be called from host functions."]
pub fn extism_current_plugin_memory(plugin: *mut ExtismCurrentPlugin) -> *mut u8;
}
extern "C" {
#[doc = " Allocate a memory block in the currently running plugin\n NOTE: this should only be called from host functions."]
pub fn extism_current_plugin_memory_alloc(
plugin: *mut ExtismCurrentPlugin,
n: ExtismSize,
) -> u64;
}
extern "C" {
#[doc = " Get the length of an allocated block\n NOTE: this should only be called from host functions."]
pub fn extism_current_plugin_memory_length(
plugin: *mut ExtismCurrentPlugin,
n: ExtismSize,
) -> ExtismSize;
}
extern "C" {
#[doc = " Free an allocated memory block\n NOTE: this should only be called from host functions."]
pub fn extism_current_plugin_memory_free(plugin: *mut ExtismCurrentPlugin, ptr: u64);
}
extern "C" {
#[doc = " Create a new host function\n\n Arguments\n - `name`: function name, this should be valid UTF-8\n - `inputs`: argument types\n - `n_inputs`: number of argument types\n - `outputs`: return types\n - `n_outputs`: number of return types\n - `func`: the function to call\n - `user_data`: a pointer that will be passed to the function when it's called\n this value should live as long as the function exists\n - `free_user_data`: a callback to release the `user_data` value when the resulting\n `ExtismFunction` is freed.\n\n Returns a new `ExtismFunction` or `null` if the `name` argument is invalid."]
pub fn extism_function_new(
name: *const ::std::os::raw::c_char,
inputs: *const ExtismValType,
n_inputs: ExtismSize,
outputs: *const ExtismValType,
n_outputs: ExtismSize,
func: ExtismFunctionType,
user_data: *mut ::std::os::raw::c_void,
free_user_data: ::std::option::Option<
unsafe extern "C" fn(__: *mut ::std::os::raw::c_void),
>,
) -> *mut ExtismFunction;
}
extern "C" {
#[doc = " Set the namespace of an `ExtismFunction`"]
pub fn extism_function_set_namespace(
ptr: *mut ExtismFunction,
namespace_: *const ::std::os::raw::c_char,
);
}
extern "C" {
#[doc = " Free an `ExtismFunction`"]
pub fn extism_function_free(ptr: *mut ExtismFunction);
}
extern "C" {
#[doc = " Create a new plugin with additional host functions\n\n `wasm`: is a WASM module (wat or wasm) or a JSON encoded manifest\n `wasm_size`: the length of the `wasm` parameter\n `functions`: an array of `ExtismFunction*`\n `n_functions`: the number of functions provided\n `with_wasi`: enables/disables WASI"]
pub fn extism_plugin_new(
ctx: *mut ExtismContext,
wasm: *const u8,
wasm_size: ExtismSize,
functions: *mut *const ExtismFunction,
n_functions: ExtismSize,
with_wasi: bool,
) -> ExtismPlugin;
}
extern "C" {
#[doc = " Update a plugin, keeping the existing ID\n\n Similar to `extism_plugin_new` but takes an `index` argument to specify\n which plugin to update\n\n Memory for this plugin will be reset upon update"]
pub fn extism_plugin_update(
ctx: *mut ExtismContext,
index: ExtismPlugin,
wasm: *const u8,
wasm_size: ExtismSize,
functions: *mut *const ExtismFunction,
nfunctions: ExtismSize,
with_wasi: bool,
) -> bool;
}
extern "C" {
#[doc = " Remove a plugin from the registry and free associated memory"]
pub fn extism_plugin_free(ctx: *mut ExtismContext, plugin: ExtismPlugin);
}
extern "C" {
#[doc = " Get plugin ID for cancellation"]
pub fn extism_plugin_cancel_handle(
ctx: *mut ExtismContext,
plugin: ExtismPlugin,
) -> *const ExtismCancelHandle;
}
extern "C" {
#[doc = " Cancel a running plugin"]
pub fn extism_plugin_cancel(handle: *const ExtismCancelHandle) -> bool;
}
extern "C" {
#[doc = " Remove all plugins from the registry"]
pub fn extism_context_reset(ctx: *mut ExtismContext);
}
extern "C" {
#[doc = " Update plugin config values, this will merge with the existing values"]
pub fn extism_plugin_config(
ctx: *mut ExtismContext,
plugin: ExtismPlugin,
@@ -48,6 +263,7 @@ extern "C" {
) -> bool;
}
extern "C" {
#[doc = " Returns true if `func_name` exists"]
pub fn extism_plugin_function_exists(
ctx: *mut ExtismContext,
plugin: ExtismPlugin,
@@ -55,6 +271,7 @@ extern "C" {
) -> bool;
}
extern "C" {
#[doc = " Call a function\n\n `func_name`: is the function to call\n `data`: is the input data\n `data_len`: is the length of `data`"]
pub fn extism_plugin_call(
ctx: *mut ExtismContext,
plugin_id: ExtismPlugin,
@@ -64,26 +281,29 @@ extern "C" {
) -> i32;
}
extern "C" {
#[doc = " Get the error associated with a `Context` or `Plugin`, if `plugin` is `-1` then the context\n error will be returned"]
pub fn extism_error(
ctx: *mut ExtismContext,
plugin: ExtismPlugin,
) -> *const ::std::os::raw::c_char;
}
extern "C" {
#[doc = " Get the length of a plugin's output data"]
pub fn extism_plugin_output_length(ctx: *mut ExtismContext, plugin: ExtismPlugin)
-> ExtismSize;
}
extern "C" {
#[doc = " Get a pointer to the output data"]
pub fn extism_plugin_output_data(ctx: *mut ExtismContext, plugin: ExtismPlugin) -> *const u8;
}
extern "C" {
#[doc = " Set log file and level"]
pub fn extism_log_file(
filename: *const ::std::os::raw::c_char,
log_level: *const ::std::os::raw::c_char,
) -> bool;
}
extern "C" {
pub fn extism_version(
) -> *const ::std::os::raw::c_char;
#[doc = " Get the Extism version string"]
pub fn extism_version() -> *const ::std::os::raw::c_char;
}

View File

@@ -1,6 +1,6 @@
pub use extism_manifest::{self as manifest, Manifest};
pub use extism_runtime::{
sdk as bindings, Function, Internal as CurrentPlugin, MemoryBlock, UserData, Val, ValType,
sdk as bindings, Function, Internal as CurrentPlugin, InternalExt, UserData, Val, ValType,
};
mod context;
@@ -44,14 +44,20 @@ mod tests {
const WASM: &[u8] = include_bytes!("../../wasm/code-functions.wasm");
const WASM_LOOP: &[u8] = include_bytes!("../../wasm/loop.wasm");
const WASM_GLOBALS: &[u8] = include_bytes!("../../wasm/globals.wasm");
const REFLECT_WASM: &[u8] = include_bytes!("../../wasm/reflect.wasm");
fn hello_world(
_plugin: &mut CurrentPlugin,
plugin: &mut CurrentPlugin,
inputs: &[Val],
outputs: &mut [Val],
_user_data: UserData,
) -> Result<(), Error> {
outputs[0] = inputs[0].clone();
let input_offs = inputs[0].unwrap_i64() as u64;
let length = plugin.memory_length(input_offs);
let input = plugin.memory_read(input_offs, length).to_vec();
let output = plugin.memory_alloc_bytes(&input).unwrap();
outputs[0] = Val::I64(output as i64);
Ok(())
}
@@ -277,10 +283,63 @@ mod tests {
});
let start = std::time::Instant::now();
let _output = plugin.call("infinite_loop", "abc123");
let _output = plugin.call("infinite_loop", "");
let end = std::time::Instant::now();
let time = end - start;
println!("Cancelled plugin ran for {:?}", time);
// std::io::stdout().write_all(output).unwrap();
}
#[test]
fn test_multiple_instantiations() {
let f = Function::new(
"hello_world",
[ValType::I64],
[ValType::I64],
None,
hello_world,
);
let context = Context::new();
let mut plugin = Plugin::new(&context, WASM, [f], true).unwrap();
// This is 10,001 because the wasmtime store limit is 10,000 - we want to test
// that our reinstantiation process is working and that limit is never hit.
for _ in 0..10001 {
let _output = plugin.call("count_vowels", "abc123").unwrap();
}
}
#[test]
fn test_globals() {
let context = Context::new();
let mut plugin = Plugin::new(&context, WASM_GLOBALS, [], true).unwrap();
for i in 0..1000 {
let output = plugin.call("globals", "").unwrap();
let count: serde_json::Value = serde_json::from_slice(&output).unwrap();
assert_eq!(count.get("count").unwrap().as_i64().unwrap(), i);
}
}
#[test]
fn test_fuzz_reflect_plugin() {
// assert!(set_log_file("stdout", Some(log::Level::Trace)));
let f = Function::new(
"host_reflect",
[ValType::I64],
[ValType::I64],
None,
hello_world,
);
let context = Context::new();
let mut plugin = Plugin::new(&context, REFLECT_WASM, [f], true).unwrap();
for i in 1..65540 {
let input = "a".repeat(i);
let output = plugin.call("reflect", input.clone());
let output = std::str::from_utf8(output.unwrap()).unwrap();
assert_eq!(output, input);
}
}
}

View File

@@ -232,8 +232,8 @@ impl<'a> Plugin<'a> {
/// Call a function with the given input and call a callback with the output, this should be preferred when
/// a single plugin may be acessed from multiple threads because the lock on the plugin is held during the
/// callback, ensuring the output value is protected from modification.
pub fn call_map<T, F: FnOnce(&'a [u8]) -> Result<T, Error>>(
&mut self,
pub fn call_map<'b, T, F: FnOnce(&'b [u8]) -> Result<T, Error>>(
&'b mut self,
name: impl AsRef<str>,
input: impl AsRef<[u8]>,
f: F,
@@ -268,11 +268,11 @@ impl<'a> Plugin<'a> {
}
/// Call a function with the given input
pub fn call(
&mut self,
pub fn call<'b>(
&'b mut self,
name: impl AsRef<str>,
input: impl AsRef<[u8]>,
) -> Result<&'a [u8], Error> {
) -> Result<&'b [u8], Error> {
self.call_map(name, input, |x| Ok(x))
}
}

Binary file not shown.

BIN
wasm/globals.wasm Executable file

Binary file not shown.

BIN
wasm/reflect.wasm Normal file

Binary file not shown.

View File

@@ -1,8 +1,15 @@
const std = @import("std");
const builtin = @import("builtin");
pub fn build(b: *std.Build) void {
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
comptime {
const current_zig = builtin.zig_version;
const min_zig = std.SemanticVersion.parse("0.12.0-dev.64+b835fd90c") catch unreachable; // std.json.ArrayHashMap
if (current_zig.order(min_zig) == .lt) {
@compileError(std.fmt.comptimePrint("Your Zig version v{} does not meet the minimum build requirement of v{}", .{ current_zig, min_zig }));
}
}
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
@@ -23,8 +30,8 @@ pub fn build(b: *std.Build) void {
tests.addAnonymousModule("extism", .{ .source_file = .{ .path = "src/main.zig" } });
tests.linkLibC();
tests.addIncludePath("/usr/local/include");
tests.addLibraryPath("/usr/local/lib");
tests.addIncludePath(.{ .path = "/usr/local/include" });
tests.addLibraryPath(.{ .path = "/usr/local/lib" });
tests.linkSystemLibrary("extism");
const tests_run_step = b.addRunArtifact(tests);
@@ -40,8 +47,8 @@ pub fn build(b: *std.Build) void {
example.addAnonymousModule("extism", .{ .source_file = .{ .path = "src/main.zig" } });
example.linkLibC();
example.addIncludePath("/usr/local/include");
example.addLibraryPath("/usr/local/lib");
example.addIncludePath(.{ .path = "/usr/local/include" });
example.addLibraryPath(.{ .path = "/usr/local/lib" });
example.linkSystemLibrary("extism");
const example_run_step = b.addRunArtifact(example);

View File

@@ -9,7 +9,7 @@ const manifest = sdk.manifest;
export fn hello_world(plugin_ptr: ?*sdk.c.ExtismCurrentPlugin, inputs: [*c]const sdk.c.ExtismVal, n_inputs: u64, outputs: [*c]sdk.c.ExtismVal, n_outputs: u64, user_data: ?*anyopaque) callconv(.C) void {
std.debug.print("Hello from Zig!\n", .{});
const str_ud = @ptrCast([*:0]const u8, user_data orelse unreachable);
const str_ud = @as([*:0]const u8, @ptrCast(user_data orelse unreachable));
std.debug.print("User data: {s}\n", .{str_ud});
var input_slice = inputs[0..n_inputs];
var output_slice = outputs[0..n_outputs];
@@ -33,16 +33,16 @@ pub fn main() !void {
&[_]sdk.c.ExtismValType{sdk.c.I64},
&[_]sdk.c.ExtismValType{sdk.c.I64},
&hello_world,
@constCast(@ptrCast(*const anyopaque, "user data")),
@constCast(@as(*const anyopaque, @ptrCast("user data"))),
);
defer f.deinit();
var my_plugin = try Plugin.initFromManifest(allocator, &context, man, &[_]Function{f}, true);
// var my_plugin = try Plugin.init(allocator, &context, wasm, &[_]Function{f}, true);
defer my_plugin.deinit();
var config = std.StringHashMap([]const u8).init(allocator);
defer config.deinit();
try config.put("thing", "this is a really important thing");
var config = std.json.ArrayHashMap([]const u8){};
defer config.deinit(allocator);
try config.map.put(allocator, "thing", "this is a really important thing");
try my_plugin.setConfig(allocator, config);
const input = "aeiouAEIOU____________________________________&smtms_y?" ** 1182;

View File

@@ -13,7 +13,7 @@ pub fn getMemory(self: Self, offset: u64) []const u8 {
const len = c.extism_current_plugin_memory_length(self.c_currplugin, offset);
const c_data = c.extism_current_plugin_memory(self.c_currplugin);
const data: [*:0]u8 = std.mem.span(c_data);
return (data + offset)[0..len];
return data[offset .. offset + len];
}
pub fn alloc(self: *Self, n: u64) u64 {
@@ -31,10 +31,10 @@ pub fn length(self: *Self, offset: u64) u64 {
pub fn returnBytes(self: *Self, val: *const c.ExtismVal, data: []const u8) void {
const mem = self.alloc(@as(u64, data.len));
const ptr = self.getMemory(mem);
std.mem.copy(u8, ptr, data);
@memcpy(ptr, data);
val.v.i64 = @as(i64, mem);
}
pub fn inputBytes(self: *Self, val: *const c.ExtismVal) []const u8 {
return self.getMemory(@intCast(u64, val.v.i64));
return self.getMemory(@intCast(val.v.i64));
}

View File

@@ -13,16 +13,27 @@ pub const WasmUrl = struct {
hash: ?[]const u8 = null,
name: ?[]const u8 = null,
method: ?[]const u8 = null,
headers: ?std.StringHashMap([]const u8) = null,
headers: ?std.json.ArrayHashMap([]const u8) = null,
};
pub const Wasm = union(enum) { wasm_data: WasmData, wasm_file: WasmFile, wasm_url: WasmUrl };
pub const Wasm = union(enum) {
wasm_data: WasmData,
wasm_file: WasmFile,
wasm_url: WasmUrl,
pub fn jsonStringify(self: @This(), jws: anytype) !void {
switch (self) {
inline else => |value| {
try jws.write(value);
},
}
}
};
pub const Manifest = struct {
wasm: []const Wasm,
memory: ?struct { max_pages: ?u32 } = null,
config: ?std.StringHashMap([]const u8) = null,
config: ?std.json.ArrayHashMap([]const u8) = null,
allowed_hosts: ?[]const []const u8 = null,
allowed_paths: ?std.StringHashMap([]const u8) = null,
allowed_paths: ?std.json.ArrayHashMap([]const u8) = null,
timeout: ?usize = null,
};

View File

@@ -4,7 +4,6 @@ const Manifest = @import("manifest.zig").Manifest;
const Function = @import("function.zig");
const CancelHandle = @import("cancel_handle.zig");
const c = @import("ffi.zig");
const utils = @import("utils.zig");
const Self = @This();
@@ -52,7 +51,7 @@ pub fn init(allocator: std.mem.Allocator, ctx: *Context, data: []const u8, funct
/// Create a new plugin from the given manifest
pub fn initFromManifest(allocator: std.mem.Allocator, ctx: *Context, manifest: Manifest, functions: []const Function, wasi: bool) !Self {
const json = try utils.stringifyAlloc(allocator, manifest);
const json = try std.json.stringifyAlloc(allocator, manifest, .{ .emit_null_optional_fields = false });
defer allocator.free(json);
return init(allocator, ctx, json, functions, wasi);
}
@@ -67,7 +66,7 @@ pub fn create(allocator: std.mem.Allocator, data: []const u8, functions: []const
/// Create a new plugin from the given manifest in its own context
pub fn createFromManifest(allocator: std.mem.Allocator, manifest: Manifest, functions: []const Function, wasi: bool) !Self {
const json = try utils.stringifyAlloc(allocator, manifest);
const json = try std.json.stringifyAlloc(allocator, manifest, .{ .emit_null_optional_fields = false });
defer allocator.free(json);
return create(allocator, json, functions, wasi);
}
@@ -128,15 +127,15 @@ pub fn update(self: *Self, data: []const u8, wasi: bool) !void {
/// Update a plugin with the given manifest
pub fn updateWithManifest(self: *Self, allocator: std.mem.Allocator, manifest: Manifest, wasi: bool) !void {
const json = try utils.stringifyAlloc(allocator, manifest);
const json = try std.json.stringifyAlloc(allocator, manifest, .{ .emit_null_optional_fields = false });
defer allocator.free(json);
return self.update(json, wasi);
}
/// Set configuration values
pub fn setConfig(self: *Self, allocator: std.mem.Allocator, config: std.StringHashMap([]const u8)) !void {
pub fn setConfig(self: *Self, allocator: std.mem.Allocator, config: std.json.ArrayHashMap([]const u8)) !void {
self.ctx.mutex.lock();
defer self.ctx.mutex.unlock();
const config_json = try utils.stringifyAlloc(allocator, config);
const config_json = try std.json.stringifyAlloc(allocator, config, .{ .emit_null_optional_fields = false });
defer allocator.free(config_json);
_ = c.extism_plugin_config(self.ctx.ctx, self.id, config_json.ptr, @as(u64, config_json.len));
}

View File

@@ -1,185 +0,0 @@
const std = @import("std");
const json = std.json;
pub fn stringifyAlloc(allocator: std.mem.Allocator, value: anytype) ![]const u8 {
var list = std.ArrayList(u8).init(allocator);
errdefer list.deinit();
try stringify(value, .{ .emit_null_optional_fields = false }, list.writer());
return list.toOwnedSlice();
}
fn stringify(
value: anytype,
options: json.StringifyOptions,
out_stream: anytype,
) @TypeOf(out_stream).Error!void {
const T = @TypeOf(value);
if (comptime std.mem.count(u8, @typeName(T), "hash_map.HashMap") > 0 and std.mem.count(u8, @typeName(T), "?") == 0) {
var it = value.iterator();
try out_stream.writeByte('{');
var i: usize = 0;
while (it.next()) |entry| {
i += 1;
const name = entry.key_ptr.*;
try json.encodeJsonString(name, options, out_stream);
if (i < value.count()) try out_stream.writeByte(':');
const val = entry.value_ptr.*;
try json.encodeJsonString(val, options, out_stream);
}
try out_stream.writeByte('}');
return;
}
switch (@typeInfo(T)) {
.Float, .ComptimeFloat => {
return std.fmt.formatFloatScientific(value, std.fmt.FormatOptions{}, out_stream);
},
.Int, .ComptimeInt => {
return std.fmt.formatIntValue(value, "", std.fmt.FormatOptions{}, out_stream);
},
.Bool => {
return out_stream.writeAll(if (value) "true" else "false");
},
.Null => {
return out_stream.writeAll("null");
},
.Optional => {
if (value) |payload| {
return try stringify(payload, options, out_stream);
} else {
return try stringify(null, options, out_stream);
}
},
.Enum => {
if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
return value.jsonStringify(options, out_stream);
}
@compileError("Unable to stringify enum '" ++ @typeName(T) ++ "'");
},
.Union => {
if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
return value.jsonStringify(options, out_stream);
}
const info = @typeInfo(T).Union;
if (info.tag_type) |UnionTagType| {
inline for (info.fields) |u_field| {
if (value == @field(UnionTagType, u_field.name)) {
return try stringify(@field(value, u_field.name), options, out_stream);
}
}
} else {
@compileError("Unable to stringify untagged union '" ++ @typeName(T) ++ "'");
}
},
.Struct => |S| {
if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
return value.jsonStringify(options, out_stream);
}
try out_stream.writeByte('{');
var field_output = false;
var child_options = options;
if (child_options.whitespace) |*child_whitespace| {
child_whitespace.indent_level += 1;
}
inline for (S.fields) |Field| {
// don't include void fields
if (Field.type == void) continue;
var emit_field = true;
// don't include optional fields that are null when emit_null_optional_fields is set to false
if (@typeInfo(Field.type) == .Optional) {
if (options.emit_null_optional_fields == false) {
if (@field(value, Field.name) == null) {
emit_field = false;
}
}
}
if (emit_field) {
if (!field_output) {
field_output = true;
} else {
try out_stream.writeByte(',');
}
if (child_options.whitespace) |child_whitespace| {
try child_whitespace.outputIndent(out_stream);
}
try json.encodeJsonString(Field.name, options, out_stream);
try out_stream.writeByte(':');
if (child_options.whitespace) |child_whitespace| {
if (child_whitespace.separator) {
try out_stream.writeByte(' ');
}
}
try stringify(@field(value, Field.name), child_options, out_stream);
}
}
if (field_output) {
if (options.whitespace) |whitespace| {
try whitespace.outputIndent(out_stream);
}
}
try out_stream.writeByte('}');
return;
},
.ErrorSet => return stringify(@as([]const u8, @errorName(value)), options, out_stream),
.Pointer => |ptr_info| switch (ptr_info.size) {
.One => switch (@typeInfo(ptr_info.child)) {
.Array => {
const Slice = []const std.meta.Elem(ptr_info.child);
return stringify(@as(Slice, value), options, out_stream);
},
else => {
// TODO: avoid loops?
std.debug.print("a: {}", .{std.mem.indexOf(u8, @typeName(T), "HashMap") != null});
// return stringify(value.*, options, out_stream);
},
},
// TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
.Slice => {
if (ptr_info.child == u8 and options.string == .String and std.unicode.utf8ValidateSlice(value)) {
try json.encodeJsonString(value, options, out_stream);
return;
}
try out_stream.writeByte('[');
var child_options = options;
if (child_options.whitespace) |*whitespace| {
whitespace.indent_level += 1;
}
for (value, 0..) |x, i| {
if (i != 0) {
try out_stream.writeByte(',');
}
if (child_options.whitespace) |child_whitespace| {
try child_whitespace.outputIndent(out_stream);
}
try stringify(x, child_options, out_stream);
}
if (value.len != 0) {
if (options.whitespace) |whitespace| {
try whitespace.outputIndent(out_stream);
}
}
try out_stream.writeByte(']');
return;
},
else => {
@compileError("Unable to stringify type '" ++ @typeName(T) ++ "'");
},
},
.Array => return stringify(&value, options, out_stream),
.Vector => |info| {
const array: [info.len]info.child = value;
return stringify(&array, options, out_stream);
},
else => {
@compileError("Unable to stringify type '" ++ @typeName(T) ++ "'");
},
}
unreachable;
}

View File

@@ -9,7 +9,7 @@ const manifest = sdk.manifest;
export fn hello_world(plugin_ptr: ?*sdk.c.ExtismCurrentPlugin, inputs: [*c]const sdk.c.ExtismVal, n_inputs: u64, outputs: [*c]sdk.c.ExtismVal, n_outputs: u64, user_data: ?*anyopaque) callconv(.C) void {
std.debug.print("Hello from Zig!\n", .{});
const str_ud = @ptrCast([*:0]const u8, user_data orelse unreachable);
const str_ud = @as([*:0]const u8, @ptrCast(user_data orelse unreachable));
std.debug.print("User data: {s}\n", .{str_ud});
var input_slice = inputs[0..n_inputs];
var output_slice = outputs[0..n_outputs];
@@ -34,7 +34,7 @@ test "Single threaded tests" {
&[_]sdk.c.ExtismValType{sdk.c.I64},
&[_]sdk.c.ExtismValType{sdk.c.I64},
&hello_world,
@constCast(@ptrCast(*const anyopaque, "user data")),
@constCast(@as(*const anyopaque, @ptrCast("user data"))),
);
defer f.deinit();
@@ -85,7 +85,7 @@ test "Multi threaded tests" {
&[_]sdk.c.ExtismValType{sdk.c.I64},
&[_]sdk.c.ExtismValType{sdk.c.I64},
&hello_world,
@constCast(@ptrCast(*const anyopaque, "user data")),
@constCast(@as(*const anyopaque, @ptrCast("user data"))),
);
defer f.deinit();
var plugin = try Plugin.initFromManifest(testing.allocator, &ctx, man, &[_]Function{f}, true);
@@ -107,7 +107,7 @@ test "Multi threaded tests" {
&[_]sdk.c.ExtismValType{sdk.c.I64},
&[_]sdk.c.ExtismValType{sdk.c.I64},
&hello_world,
@constCast(@ptrCast(*const anyopaque, "user data")),
@constCast(@as(*const anyopaque, @ptrCast("user data"))),
);
defer f.deinit();
@@ -129,7 +129,7 @@ test "Plugin Cancellation" {
&[_]sdk.c.ExtismValType{sdk.c.I64},
&[_]sdk.c.ExtismValType{sdk.c.I64},
&hello_world,
@constCast(@ptrCast(*const anyopaque, "user data")),
@constCast(@as(*const anyopaque, @ptrCast("user data"))),
);
defer f.deinit();