or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

components.mdcore-runtime.mderrors.mdfunctions.mdindex.mdlinking.mdmemory.mdtypes.mdutilities.mdwasi.md

linking.mddocs/

0

# Module Linking

1

2

Advanced module linking system for resolving imports, connecting multiple WebAssembly modules, and creating complex WebAssembly applications with shared functionality, WASI integration, and dynamic module loading.

3

4

## Capabilities

5

6

### Linker Management

7

8

Central linking system managing module imports, instance creation, and cross-module communication with support for shadowing, WASI integration, and complex dependency resolution.

9

10

```python { .api }

11

class Linker:

12

def __init__(self, engine: Engine):

13

"""

14

Create a new linker for the given engine.

15

16

Parameters:

17

- engine: WebAssembly engine for linking context

18

"""

19

20

def allow_shadowing(self, enable: bool) -> None:

21

"""

22

Configure whether export shadowing is allowed.

23

24

Parameters:

25

- enable: True to allow shadowing, False to error on conflicts

26

"""

27

28

def define(self, store: Store, module: str, name: str, item) -> None:

29

"""

30

Define an import with a specific module and name.

31

32

Parameters:

33

- store: Store context

34

- module: Module name for the import

35

- name: Import name within the module

36

- item: Export object (Func, Memory, Table, or Global)

37

"""

38

39

def define_func(self, module: str, name: str, ty: FuncType, func: Callable) -> None:

40

"""

41

Define a function import directly from Python callable.

42

43

Parameters:

44

- module: Module name for the import

45

- name: Function name within the module

46

- ty: Function type signature

47

- func: Python callable implementing the function

48

"""

49

50

def define_wasi(self, store: Store, wasi_config: WasiConfig) -> None:

51

"""

52

Define WASI imports using the given configuration.

53

54

Parameters:

55

- store: Store context

56

- wasi_config: WASI configuration for system interface

57

"""

58

59

def define_instance(self, store: Store, name: str, instance: Instance) -> None:

60

"""

61

Define all exports from an instance as imports.

62

63

Parameters:

64

- store: Store context

65

- name: Module name for the instance exports

66

- instance: WebAssembly instance to export

67

"""

68

69

def instantiate(self, store: Store, module: Module) -> Instance:

70

"""

71

Instantiate a module using defined imports.

72

73

Parameters:

74

- store: Store context

75

- module: WebAssembly module to instantiate

76

77

Returns:

78

Instantiated WebAssembly instance

79

80

Raises:

81

WasmtimeError: If imports don't satisfy module requirements

82

"""

83

84

def get_default(self, store: Store, name: str):

85

"""

86

Get the default export for a module.

87

88

Parameters:

89

- store: Store context

90

- name: Module name

91

92

Returns:

93

Default export object if available

94

"""

95

```

96

97

## Usage Examples

98

99

### Basic Module Linking

100

101

```python

102

import wasmtime

103

104

# Create engine and linker

105

engine = wasmtime.Engine()

106

linker = wasmtime.Linker(engine)

107

store = wasmtime.Store(engine)

108

109

# Define host functions for import

110

def host_print(message_ptr: int, message_len: int) -> None:

111

# Implementation would read from memory and print

112

print(f"Host print called with ptr={message_ptr}, len={message_len}")

113

114

print_type = wasmtime.FuncType([wasmtime.ValType.I32, wasmtime.ValType.I32], [])

115

linker.define_func("host", "print", print_type, host_print)

116

117

# Define memory for sharing between modules

118

memory_type = wasmtime.MemoryType(wasmtime.Limits(1, 10))

119

shared_memory = wasmtime.Memory(store, memory_type)

120

linker.define(store, "env", "memory", shared_memory)

121

122

# Load and instantiate module

123

module = wasmtime.Module.from_file(engine, "program.wasm")

124

instance = linker.instantiate(store, module)

125

126

print("Module instantiated with host imports")

127

```

128

129

### Multi-Module Application

130

131

```python

132

import wasmtime

133

134

engine = wasmtime.Engine()

135

linker = wasmtime.Linker(engine)

136

store = wasmtime.Store(engine)

137

138

# Load utility module first

139

utils_module = wasmtime.Module.from_file(engine, "utils.wasm")

140

utils_instance = linker.instantiate(store, utils_module)

141

142

# Make utils exports available to other modules

143

linker.define_instance(store, "utils", utils_instance)

144

145

# Load main application module that imports from utils

146

app_module = wasmtime.Module.from_file(engine, "app.wasm")

147

app_instance = linker.instantiate(store, app_module)

148

149

# Now app can use functions from utils module

150

main_func = app_instance.get_export(store, "main")

151

result = main_func(store)

152

print(f"Application result: {result}")

153

```

154

155

### WASI Application with Custom Imports

156

157

```python

158

import wasmtime

159

import time

160

161

# Custom host functions for the application

162

def get_timestamp() -> int:

163

"""Return current Unix timestamp"""

164

return int(time.time())

165

166

def sleep_ms(milliseconds: int) -> None:

167

"""Sleep for specified milliseconds"""

168

time.sleep(milliseconds / 1000.0)

169

170

# Set up linker with custom functions

171

engine = wasmtime.Engine()

172

linker = wasmtime.Linker(engine)

173

store = wasmtime.Store(engine)

174

175

# Define custom host functions

176

timestamp_type = wasmtime.FuncType([], [wasmtime.ValType.I32])

177

sleep_type = wasmtime.FuncType([wasmtime.ValType.I32], [])

178

179

linker.define_func("host", "get_timestamp", timestamp_type, get_timestamp)

180

linker.define_func("host", "sleep_ms", sleep_type, sleep_ms)

181

182

# Configure and define WASI

183

wasi_config = wasmtime.WasiConfig()

184

wasi_config.inherit_argv()

185

wasi_config.inherit_env()

186

wasi_config.inherit_stdin()

187

wasi_config.inherit_stdout()

188

wasi_config.inherit_stderr()

189

linker.define_wasi(store, wasi_config)

190

191

# Load and run WASI application with custom imports

192

module = wasmtime.Module.from_file(engine, "wasi_app.wasm")

193

instance = linker.instantiate(store, module)

194

195

# Start the application

196

try:

197

start_func = instance.get_export(store, "_start")

198

start_func(store)

199

except wasmtime.ExitTrap as exit_trap:

200

print(f"Application exited with code: {exit_trap.code}")

201

```

202

203

### Dynamic Module Loading

204

205

```python

206

import wasmtime

207

import os

208

209

class ModuleLoader:

210

def __init__(self, engine: wasmtime.Engine):

211

self.engine = engine

212

self.linker = wasmtime.Linker(engine)

213

self.store = wasmtime.Store(engine)

214

self.loaded_modules = {}

215

216

# Allow shadowing for dynamic loading

217

self.linker.allow_shadowing(True)

218

219

# Set up WASI by default

220

wasi_config = wasmtime.WasiConfig()

221

wasi_config.inherit_argv()

222

wasi_config.inherit_env()

223

wasi_config.inherit_stdin()

224

wasi_config.inherit_stdout()

225

wasi_config.inherit_stderr()

226

self.linker.define_wasi(self.store, wasi_config)

227

228

def load_module(self, name: str, path: str) -> wasmtime.Instance:

229

"""Load a WebAssembly module and make its exports available"""

230

if name in self.loaded_modules:

231

return self.loaded_modules[name]

232

233

# Load and instantiate module

234

module = wasmtime.Module.from_file(self.engine, path)

235

instance = self.linker.instantiate(self.store, module)

236

237

# Make this module's exports available to future modules

238

self.linker.define_instance(self.store, name, instance)

239

240

# Cache the instance

241

self.loaded_modules[name] = instance

242

243

print(f"Loaded module '{name}' from {path}")

244

return instance

245

246

def get_module(self, name: str) -> wasmtime.Instance:

247

"""Get a previously loaded module"""

248

if name not in self.loaded_modules:

249

raise ValueError(f"Module '{name}' not loaded")

250

return self.loaded_modules[name]

251

252

# Usage example

253

engine = wasmtime.Engine()

254

loader = ModuleLoader(engine)

255

256

# Load modules in dependency order

257

math_instance = loader.load_module("math", "math_utils.wasm")

258

string_instance = loader.load_module("string", "string_utils.wasm")

259

app_instance = loader.load_module("app", "main_app.wasm")

260

261

# The main app can now use functions from both math and string modules

262

```

263

264

### Import Resolution with Error Handling

265

266

```python

267

import wasmtime

268

269

def safe_module_linking(engine: wasmtime.Engine, module_path: str, imports_config: dict):

270

"""

271

Safely link and instantiate a module with comprehensive error handling.

272

273

Parameters:

274

- engine: WebAssembly engine

275

- module_path: Path to WebAssembly module

276

- imports_config: Dictionary of import configurations

277

"""

278

279

linker = wasmtime.Linker(engine)

280

store = wasmtime.Store(engine)

281

282

try:

283

# Load the module first to check its imports

284

module = wasmtime.Module.from_file(engine, module_path)

285

286

print(f"Module requires {len(module.imports)} imports:")

287

for import_item in module.imports:

288

print(f" {import_item.module}.{import_item.name}: {import_item.type}")

289

290

# Define imports based on configuration

291

for import_item in module.imports:

292

module_name = import_item.module

293

item_name = import_item.name

294

295

if module_name in imports_config:

296

if item_name in imports_config[module_name]:

297

import_obj = imports_config[module_name][item_name]

298

linker.define(store, module_name, item_name, import_obj)

299

print(f" ✓ Resolved {module_name}.{item_name}")

300

else:

301

print(f" ✗ Missing import: {module_name}.{item_name}")

302

else:

303

print(f" ✗ Missing module: {module_name}")

304

305

# Try to instantiate

306

print("Attempting instantiation...")

307

instance = linker.instantiate(store, module)

308

print("✓ Module instantiated successfully")

309

310

return instance

311

312

except wasmtime.WasmtimeError as e:

313

if "unknown import" in str(e):

314

print(f"✗ Import resolution failed: {e}")

315

print("Available imports in linker:")

316

# Note: Wasmtime doesn't provide a way to list available imports

317

print(" (Check your imports_config)")

318

else:

319

print(f"✗ Linking error: {e}")

320

return None

321

322

except FileNotFoundError:

323

print(f"✗ Module file not found: {module_path}")

324

return None

325

326

except Exception as e:

327

print(f"✗ Unexpected error: {e}")

328

return None

329

330

# Example usage

331

engine = wasmtime.Engine()

332

store = wasmtime.Store(engine)

333

334

# Create some sample imports

335

memory = wasmtime.Memory(store, wasmtime.MemoryType(wasmtime.Limits(1)))

336

print_func = wasmtime.Func(store,

337

wasmtime.FuncType([wasmtime.ValType.I32], []),

338

lambda x: print(f"Printed: {x}"))

339

340

imports_config = {

341

"env": {

342

"memory": memory,

343

"print": print_func

344

}

345

}

346

347

instance = safe_module_linking(engine, "test_module.wasm", imports_config)

348

if instance:

349

# Use the instance...

350

pass

351

```