Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve doc #345

Merged
merged 5 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion next/_ext/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ class MoonBitLexer(RegexLexer):
(r"\$\|", token.String, "string.multiline"),
(r"0(b|B)[01]+", token.Number.Bin),
(r"0(o|O)[0-7]+", token.Number.Oct),
(r"0(x|X)[0-9a-fA-F]+", token.Number.Hex),
(r"0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\.[0-9a-fA-F][0-9a-fA-F_]*(P|p)(\+|\-)?[0-9][0-9]*", token.Number.Float),
(r"0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\.?(P|p)(\+|\-)?[0-9][0-9]*", token.Number.Float),
(r"0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\.[0-9a-fA-F][0-9a-fA-F_]*", token.Number.Float),
(r"0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\.", token.Number.Float),
(r"0(x|X)[0-9a-fA-F][0-9a-fA-F_]*", token.Number.Hex),
(r"\d(_|\d)*U?L", token.Number.Integer.Long),
(r"\d(_|\d)*U?", token.Number.Integer),
(r"\d+(.\d+)?", token.Number),
Expand Down
50 changes: 26 additions & 24 deletions next/language/ffi-and-wasm-host.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# Foreign Function Interface(FFI)

What we've introduced is about describing pure computation. In reality, you'll need
to interact with the real world. However, the "world" is different for each backend (C, JS, Wasm, WasmGC)
and is sometimes based on runtime ([Wasmtime](https://wasmtime.dev/), Deno, Browser, etc.).

You can use foreign function in MoonBit through FFI to interact with the hosting runtime when embedded inside the browser or command line applications through [Wasmtime](https://wasmtime.dev/) or similar projects.

⚠ Warning: MoonBit is still in early stage, so the content may be outdated.
## Init function

## FFI
For WebAssembly backend, it is compiled as [start function](https://webassembly.github.io/spec/core/syntax/modules.html#start-function), meaning that it will be executed **before** the instance is available, and the FFIs that relies on the instance's exportations can not be used at this stage;
for JavaScript backend, it means that it will be executed during the importation stage.

### Declare Foreign Reference
## Declare Foreign Reference

You can declare a foreign reference type like this:

Expand All @@ -16,7 +21,11 @@ type Canvas_ctx

This will be a type that represents a reference to a foreign object, a `CanvasRenderingContext2D` object held by the hosting JavaScript runtime in this example.

### Declare Foreign Function
## Declare Foreign Function

You can either import a function with module name and function name or writing an inline function.

### Import function

You can declare a foreign function like this:

Expand All @@ -26,11 +35,15 @@ fn cos(d : Double) -> Double = "Math" "cos"

It's similar to a normal function definition except that the function body is replaced with two strings.

For WasmGC backend, these two strings are used to identify the specific function from a Wasm import object, the first string is the module name, and the second string is the function name. For JS backend, these two strings are used to call a static function in the global namespace. The example above becomes similar to `const cos = (d) => Math.cos(d)`.
For Wasm(GC) backend, these two strings are used to identify the specific function from a Wasm import object, the first string is the module name, and the second string is the function name.

For JS backend, these two strings are used to call a static function in the global namespace. The example above becomes similar to `const cos = (d) => Math.cos(d)`.

### Inline function

You can also declare inline functions where the function body is replaced with one string.

For WasmGC backend, you may declare it as a Wasm function without name (which will be generated afterwards):
For Wasm(GC) backend, you may declare it as a Wasm function without name (which will be generated afterwards):

```moonbit
extern "wasm" fn abs(d : Double) -> Double =
Expand All @@ -46,7 +59,7 @@ extern "js" fn abs(d : Double) -> Double =

After declaration, you can use foreign functions like regular functions.

For multi-backend project, you may implement backend specific code in the files that ends with `.wasm.mbt` `.wasm-gc.mbt` and `.js.mbt`.
For multi-backend project, you may implement backend specific code in the files that ends with `.wasm.mbt` `.wasm-gc.mbt` and `.js.mbt`. Check out [link options](</toolchain/moon/package.md#link-options>) for details.

You may also declare a foreign function that will be invoked upon a foreign object by using the foreign reference type like this:

Expand All @@ -56,30 +69,21 @@ fn begin_path(self: Canvas_ctx) = "canvas" "begin_path"

and apply it to a previously owned reference normally such as `context.begin_path()`.

### Exported functions
## Export functions

Functions that are not methods nor polymorphic functions can be exported if they are public and if the link configuration appears in the `moon.pkg.json` of the package:

```json
{
"link": {
"wasm": {
"exports": [
"add",
"fib:test"
]
"exports": [ "add", "fib:test" ]
},
"wasm-gc": {
"exports": [
"add",
"fib:test"
]
"exports": [ "add", "fib:test" ]
},
"js": {
"exports": [
"add",
"fib:test"
],
"exports": [ "add", "fib:test" ],
"format": "esm"
}
}
Expand All @@ -90,13 +94,11 @@ Each backend has a separate definition. For JS backend, a `format` option is use

The example above will export function `add` and `fib`, and the function `fib` will be exported with the name of `test`.

For WasmGC backend, the `_start` function should always be called to initialize all the global instances defined in MoonBit program.

### Use compiled Wasm
## Use compiled Wasm

To use the compiled Wasm, you need to initialize the Wasm module with the host functions so as to meet the needs of the foreign functions, and then use the exported functions provided by the Wasm module.

#### Provide host functions
### Provide host functions

To use the compiled Wasm, you must provide **All** declared foreign functions in Wasm import object.

Expand Down
Loading
Loading