The Fluence Labs Developer Hub

Welcome to the Fluence Labs developer hub. You'll find comprehensive guides and documentation to help you start working with Fluence Labs as quickly as possible, as well as support if you get stuck. Let's jump right in!

Should you have any questions, feel free to join our Discord or Telegram!

Get Started

Module linking and Interface Types

For WebAssembly execution, the Fluence node uses FCE, which allows running multi-module WebAssembly applications with the help of interface types (IT). This section contains some of the internal details of using interface types and linking modules in FCE.

Module linking

FCE uses the so-called shared-nothing linking scheme. This scheme implies that any module exposes only exported functions and keeps its memory or table inaccessible to other modules. The modules are linked only through the export and import of functions. When loading a module, FCE expects that functions declared in the module as imported have been already loaded into FCE. Otherwise, such a module cannot be loaded.

Interface types (IT)

FCE uses the modified wasmer-interface-types crate for IT execution. This crate is based on the previous revision (before Nov 2020) of the IT proposal with some additions such as swap and dup instructions.

If you are interested in the details of interface types, you can use the show command of fce, which prints the IT section of the compiled Wasm binary:

# obtain interface-types section of greeting.wasm
~ $ fce show -i artifacts/greeting.wasm
;; Types
(@interface type (func
  (param $size: i32)
  (result i32)))   ;; 0
(@interface type (func
  (param $pointer: i32 $size: i32) ))   ;; 1
(@interface type (func
  (result i32)))   ;; 2
(@interface type (func
  (result i32)))   ;; 3
(@interface type (func
  (param $result_size: i32) ))   ;; 4
(@interface type (func
  (param $result_ptr: i32) ))   ;; 5
(@interface type (record $CallParameters (
 field $call_id: string
 field $user_name: string
 field $application_id: string
)))   ;; 6
(@interface type (func
  (param $name: string)
  (result string)))   ;; 7
(@interface type (func
  (param $name: string)
  (result string)))   ;; 8

;; Adapters
(@interface func (type 7)
  arg.get 0
  string.size
  call-core 0
  arg.get 0
  string.lower_memory
  call-core 6
  call-core 3
  call-core 2
  string.lift_memory
  call-core 3
  call-core 2
  call-core 1)

;; Exports
(@interface export "allocate" (func 0))
(@interface export "deallocate" (func 1))
(@interface export "get_result_size" (func 2))
(@interface export "get_result_ptr" (func 3))
(@interface export "set_result_size" (func 4))
(@interface export "set_result_ptr" (func 5))
(@interface export "greeting" (func 8))

;; Implementations
(@interface implement (func 8) (func 7))

Also, REPL can print the trace of each IT instruction in the following way:

# specify printing each interface type intruction in `REPL`, run fce-repl and call the greeting function
~ $ RUST_LOG="wasmer_interface_types_fl=trace,info" fce-repl Config.toml
Welcome to the Fluence FaaS REPL
app service's created with service id = bfd21de5-bc89-4be5-87db-762ebb52de1c
elapsed time 42.916353ms

1> call greeting greeting "user"
[host] arg.get: pushing String("user") on the stack
[host] string.size: pushing 4 on the stack
[host] call-core: calling allocate with arguments: [I32(4)]
[host] call-core: call to 0 succeeded with result [I32(1114224)]
[host] arg.get: pushing String("user") on the stack
[host] string.lower_memory: pushing 1114224, 4 on the stack
[host] call-core: calling greeting with arguments: [I32(1114224), I32(4)]
[host] call-core: call to 6 succeeded with result []
[host] call-core: calling get_result_ptr with arguments: []
[host] call-core: call to 3 succeeded with result [I32(1114240)]
[host] call-core: calling get_result_size with arguments: []
[host] call-core: call to 2 succeeded with result [I32(8)]
[host] string.lift_memory: pushing "Hi, user" on the stack
[host] call-core: calling get_result_ptr with arguments: []
[host] call-core: call to 3 succeeded with result [I32(1114240)]
[host] call-core: calling get_result_size with arguments: []
[host] call-core: call to 2 succeeded with result [I32(8)]
[host] call-core: calling deallocate with arguments: [I32(1114240), I32(8)]
[host] call-core: call to 1 succeeded with result []
result: String("Hi, user")
 elapsed time: 366.173µs

Updated 3 months ago

Module linking and Interface Types


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.