简述
动态链接是在运行时将两个或多个模块链接在一起的过程。
为了演示动态链接的工作原理,我们将使用 C 程序并使用 Ecmascript sdk 将其编译为 wasm。
所以我们在这里 -
test1.c
int test1(){
return 100;
}
test2.c
int test2(){
return 200;
}
主程序
#include <stdio.h>
int test1();
int test2();
int main() {
int result = test1() + test2();
return result;
}
在 main.c 代码中,它使用了在 test1.c 和 test2.c 中定义的 test1() 和 test2()。让我们看看如何在 WebAssembly 中链接这些模块。
编译上述代码的命令如下:使用 SIDE_MODULE =1 进行动态链接,如命令所示。
emcc test1.c test2.c main.c -s SIDE_MODULE=1 -o maintest.wasm
使用 https://webassembly.github.io/wabt/demo/wasm2wat/ 上提供的 WasmtoWat
,将获得 maintest.wasm 的 WebAssembly 文本格式。
(module
(type $t0 (func (result i32))) (type $t1 (func))
(type $t2 (func (param i32))) (type $t3 (func (param i32 i32) (result i32)))
(import "env" "stackSave" (func $env.stackSave (type $t0)))
(import "env" "stackRestore" (func $env.stackRestore (type $t2)))
(import "env" "__memory_base" (global $env.__memory_base i32))
(import "env" "__table_base" (global $env.__table_base i32))
(import "env" "memory" (memory $env.memory 0))
(import "env" "table" (table $env.table 0 funcref))
(func $f2 (type $t1)
(call $__wasm_apply_relocs)
)
(func $__wasm_apply_relocs (export "__wasm_apply_relocs") (type $t1))
(func $test1 (export "test1") (type $t0) (result i32)
(local $l0 i32)
(local.set $l0
(i32.const 100)
)
(return
(local.get $l0)
)
)
(func $test2 (export "test2") (type $t0) (result i32)
(local $l0 i32)
(local.set $l0
(i32.const 200))
(return
(local.get $l0)
)
)
(func $__original_main
(export "__original_main")
(type $t0)
(result i32)
(local $l0 i32)
(local $l1 i32)
(local $l2 i32)
(local $l3 i32)
(local $l4 i32)
(local $l5 i32)
(local $l6 i32)
(local $l7 i32)
(local $l8 i32)
(local $l9 i32)
(local.set $l0(call $env.stackSave))
(local.set $l1 (i32.const 16))
(local.set $l2 (i32.sub (local.get $l0) (local.get $l1)))
(call $env.stackRestore (local.get $l2) ) (local.set $l3(i32.const 0))
(i32.store offset=12 (local.get $l2) (local.get $l3))
(local.set $l4 (call $test1))
(local.set $l5 (call $test2))
(local.set $l6 (i32.add (local.get $l4) (local.get $l5)))
(i32.store offset=8 (local.get $l2) (local.get $l6))
(local.set $l7 (i32.load offset=8 (local.get $l2)))
(local.set $l8 (i32.const 16))
(local.set $l9 (i32.add (local.get $l2) (local.get $l8)))
(call $env.stackRestore (local.get $l9)) (return(local.get $l7))
)
(func $main
(export "main")
(type $t3)
(param $p0 i32)
(param $p1 i32)
(result i32)
(local $l2 i32)
(local.set $l2
(call $__original_main))
(return (local.get $l2))
)
(func $__post_instantiate (export "__post_instantiate") (type $t1) (call $f2))
(global $__dso_handle (export "__dso_handle") i32 (i32.const 0))
)
WebAssembly 文本格式定义了一些导入,如下所示 -
(import "env" "stackSave" (func $env.stackSave (type $t0)))
(import "env" "stackRestore" (func $env.stackRestore (type $t2)))
(import "env" "__memory_base" (global $env.__memory_base i32))
(import "env" "__table_base" (global $env.__table_base i32))
(import "env" "memory" (memory $env.memory 0))
(import "env" "table" (table $env.table 0 funcref))
这是在 emcc(emscripten sdk) 编译代码时添加的,它处理 WebAssembly 中的内存管理。