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

utilities.mddocs/

0

# Utilities

1

2

Helper functions and utilities including WebAssembly text format conversion, table management, global variable handling, development aids, and convenience functions for common WebAssembly operations and debugging tasks.

3

4

## Capabilities

5

6

### Text Format Conversion

7

8

WebAssembly Text (WAT) to binary (WASM) conversion utility providing human-readable WebAssembly format support for development, testing, and educational purposes.

9

10

```python { .api }

11

def wat2wasm(wat: str) -> bytes:

12

"""

13

Convert WebAssembly Text format to binary format.

14

15

Parameters:

16

- wat: WebAssembly text format string

17

18

Returns:

19

Binary WebAssembly module bytes

20

21

Raises:

22

WasmtimeError: If WAT parsing or compilation fails

23

"""

24

```

25

26

### Table Management

27

28

WebAssembly table objects providing reference storage, dynamic table operations, element access, and table growth capabilities for function references and external references.

29

30

```python { .api }

31

class Table:

32

def __init__(self, store: Store, ty: TableType, init):

33

"""

34

Create a new table with specified type and initial value.

35

36

Parameters:

37

- store: Store for table allocation context

38

- ty: Table type specifying element type and size limits

39

- init: Initial value for all table elements

40

41

Raises:

42

WasmtimeError: If table creation fails

43

"""

44

45

def type(self, store: Store) -> TableType:

46

"""

47

Get the table type specification.

48

49

Parameters:

50

- store: Store context

51

52

Returns:

53

Table type with element type and current size limits

54

"""

55

56

def size(self, store: Store) -> int:

57

"""

58

Get current table size in elements.

59

60

Parameters:

61

- store: Store context

62

63

Returns:

64

Number of elements in the table

65

"""

66

67

def grow(self, store: Store, delta: int, init) -> int:

68

"""

69

Grow table by specified number of elements.

70

71

Parameters:

72

- store: Store context

73

- delta: Number of elements to add (must be non-negative)

74

- init: Initial value for new elements

75

76

Returns:

77

Previous table size in elements

78

79

Raises:

80

WasmtimeError: If growth fails or exceeds maximum size

81

"""

82

83

def get(self, store: Store, idx: int):

84

"""

85

Get element at specified index.

86

87

Parameters:

88

- store: Store context

89

- idx: Element index (zero-based)

90

91

Returns:

92

Element value at the specified index

93

94

Raises:

95

WasmtimeError: If index is out of bounds

96

"""

97

98

def set(self, store: Store, idx: int, val) -> None:

99

"""

100

Set element at specified index.

101

102

Parameters:

103

- store: Store context

104

- idx: Element index (zero-based)

105

- val: New value for the element

106

107

Raises:

108

WasmtimeError: If index is out of bounds or value type mismatch

109

"""

110

```

111

112

### Global Variables

113

114

WebAssembly global variable objects providing mutable and immutable global state, type-safe value access, and runtime global variable management for WebAssembly modules.

115

116

```python { .api }

117

class Global:

118

def __init__(self, store: Store, ty: GlobalType, val: Val):

119

"""

120

Create a new global variable with specified type and initial value.

121

122

Parameters:

123

- store: Store for global allocation context

124

- ty: Global type specifying value type and mutability

125

- val: Initial value for the global variable

126

127

Raises:

128

WasmtimeError: If global creation fails or value type mismatch

129

"""

130

131

def type(self, store: Store) -> GlobalType:

132

"""

133

Get the global variable type specification.

134

135

Parameters:

136

- store: Store context

137

138

Returns:

139

Global type with value type and mutability information

140

"""

141

142

def value(self, store: Store) -> Val:

143

"""

144

Get the current value of the global variable.

145

146

Parameters:

147

- store: Store context

148

149

Returns:

150

Current global variable value

151

"""

152

153

def set_value(self, store: Store, val: Val) -> None:

154

"""

155

Set the value of the global variable (if mutable).

156

157

Parameters:

158

- store: Store context

159

- val: New value for the global variable

160

161

Raises:

162

WasmtimeError: If global is immutable or value type mismatch

163

"""

164

```

165

166

## Usage Examples

167

168

### WAT to WASM Conversion

169

170

```python

171

import wasmtime

172

173

# Simple arithmetic module in WAT format

174

wat_code = '''

175

(module

176

(func (export "add") (param i32 i32) (result i32)

177

local.get 0

178

local.get 1

179

i32.add)

180

(func (export "multiply") (param f32 f32) (result f32)

181

local.get 0

182

local.get 1

183

f32.mul)

184

(memory (export "memory") 1)

185

(global (export "counter") (mut i32) (i32.const 0))

186

)

187

'''

188

189

# Convert WAT to WASM binary

190

try:

191

wasm_bytes = wasmtime.wat2wasm(wat_code)

192

print(f"Converted WAT to WASM: {len(wasm_bytes)} bytes")

193

194

# Use the compiled module

195

engine = wasmtime.Engine()

196

store = wasmtime.Store(engine)

197

module = wasmtime.Module(engine, wasm_bytes)

198

instance = wasmtime.Instance(store, module, [])

199

200

# Call the functions

201

add_func = instance.exports(store)["add"]

202

multiply_func = instance.exports(store)["multiply"]

203

204

result1 = add_func(store, 15, 27)

205

result2 = multiply_func(store, 3.5, 2.0)

206

207

print(f"15 + 27 = {result1}")

208

print(f"3.5 * 2.0 = {result2}")

209

210

except wasmtime.WasmtimeError as e:

211

print(f"WAT compilation failed: {e}")

212

```

213

214

### Complex WAT Example with Tables and Globals

215

216

```python

217

import wasmtime

218

219

# Advanced WAT example with tables and indirect calls

220

advanced_wat = '''

221

(module

222

;; Function type for binary operations

223

(type $binary_op (func (param i32 i32) (result i32)))

224

225

;; Function table for indirect calls

226

(table (export "functions") 4 funcref)

227

228

;; Global counter

229

(global $counter (mut i32) (i32.const 0))

230

(global (export "counter") (mut i32) (i32.const 0))

231

232

;; Binary operation functions

233

(func $add (type $binary_op)

234

local.get 0

235

local.get 1

236

i32.add)

237

238

(func $sub (type $binary_op)

239

local.get 0

240

local.get 1

241

i32.sub)

242

243

(func $mul (type $binary_op)

244

local.get 0

245

local.get 1

246

i32.mul)

247

248

(func $div (type $binary_op)

249

local.get 0

250

local.get 1

251

i32.div_s)

252

253

;; Initialize function table

254

(elem (i32.const 0) $add $sub $mul $div)

255

256

;; Indirect call function

257

(func (export "call_op") (param i32 i32 i32) (result i32)

258

;; Increment counter

259

global.get $counter

260

i32.const 1

261

i32.add

262

global.set $counter

263

264

;; Indirect call

265

local.get 1 ;; first operand

266

local.get 2 ;; second operand

267

local.get 0 ;; function index

268

call_indirect (type $binary_op))

269

270

;; Get counter value

271

(func (export "get_counter") (result i32)

272

global.get $counter)

273

)

274

'''

275

276

# Convert and use the advanced module

277

try:

278

wasm_bytes = wasmtime.wat2wasm(advanced_wat)

279

280

engine = wasmtime.Engine()

281

store = wasmtime.Store(engine)

282

module = wasmtime.Module(engine, wasm_bytes)

283

instance = wasmtime.Instance(store, module, [])

284

285

exports = instance.exports(store)

286

call_op = exports["call_op"]

287

get_counter = exports["get_counter"]

288

functions_table = exports["functions"]

289

counter_global = exports["counter"]

290

291

# Test indirect function calls

292

operations = ["add", "sub", "mul", "div"]

293

for i, op_name in enumerate(operations):

294

result = call_op(store, i, 20, 4) # function_index, a, b

295

counter = get_counter(store)

296

print(f"{op_name}(20, 4) = {result}, counter = {counter}")

297

298

# Access global directly

299

final_counter = counter_global.value(store)

300

print(f"Final counter value: {final_counter.value}")

301

302

except wasmtime.WasmtimeError as e:

303

print(f"Advanced WAT compilation failed: {e}")

304

```

305

306

### Table Operations

307

308

```python

309

import wasmtime

310

311

# Create engine and store

312

engine = wasmtime.Engine()

313

store = wasmtime.Store(engine)

314

315

# Create table type for function references (0-10 elements)

316

table_limits = wasmtime.Limits(0, 10)

317

table_type = wasmtime.TableType(wasmtime.ValType.FUNCREF, table_limits)

318

319

# Create table with null initial value

320

table = wasmtime.Table(store, table_type, wasmtime.Val.funcref(None))

321

322

print(f"Created table with {table.size(store)} elements")

323

324

# Create some functions to store in the table

325

def host_func1(x: int) -> int:

326

return x * 2

327

328

def host_func2(x: int) -> int:

329

return x + 10

330

331

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

332

func1 = wasmtime.Func(store, func_type, host_func1)

333

func2 = wasmtime.Func(store, func_type, host_func2)

334

335

# Grow table to accommodate functions

336

old_size = table.grow(store, 2, wasmtime.Val.funcref(None))

337

print(f"Table grown from {old_size} to {table.size(store)} elements")

338

339

# Set functions in table

340

table.set(store, 0, func1)

341

table.set(store, 1, func2)

342

343

print("Functions stored in table")

344

345

# Retrieve and call functions from table

346

for i in range(2):

347

func_val = table.get(store, i)

348

if func_val.value is not None:

349

func = func_val.value

350

result = func(store, 5)

351

print(f"Function at index {i}: f(5) = {result}")

352

353

# Try to access out of bounds (will raise error)

354

try:

355

table.get(store, 10)

356

except wasmtime.WasmtimeError as e:

357

print(f"Expected error for out of bounds access: {e}")

358

```

359

360

### Global Variable Management

361

362

```python

363

import wasmtime

364

365

# Create engine and store

366

engine = wasmtime.Engine()

367

store = wasmtime.Store(engine)

368

369

# Create mutable global variables

370

mutable_i32_type = wasmtime.GlobalType(wasmtime.ValType.I32, True)

371

mutable_global = wasmtime.Global(store, mutable_i32_type, wasmtime.Val.i32(42))

372

373

# Create immutable global variable

374

immutable_f64_type = wasmtime.GlobalType(wasmtime.ValType.F64, False)

375

immutable_global = wasmtime.Global(store, immutable_f64_type, wasmtime.Val.f64(3.14159))

376

377

# Read global values

378

mutable_value = mutable_global.value(store)

379

immutable_value = immutable_global.value(store)

380

381

print(f"Mutable global: {mutable_value.value} (type: {mutable_value.type})")

382

print(f"Immutable global: {immutable_value.value} (type: {immutable_value.type})")

383

384

# Modify mutable global

385

print("Incrementing mutable global...")

386

current_value = mutable_global.value(store)

387

new_value = wasmtime.Val.i32(current_value.value + 1)

388

mutable_global.set_value(store, new_value)

389

390

updated_value = mutable_global.value(store)

391

print(f"Updated mutable global: {updated_value.value}")

392

393

# Try to modify immutable global (will raise error)

394

try:

395

immutable_global.set_value(store, wasmtime.Val.f64(2.71828))

396

except wasmtime.WasmtimeError as e:

397

print(f"Expected error for immutable global: {e}")

398

399

# Check global types

400

mutable_type = mutable_global.type(store)

401

immutable_type = immutable_global.type(store)

402

403

print(f"Mutable global type: {mutable_type.content}, mutable: {mutable_type.mutability}")

404

print(f"Immutable global type: {immutable_type.content}, mutable: {immutable_type.mutability}")

405

```

406

407

### Utility Functions for Development

408

409

```python

410

import wasmtime

411

import time

412

import json

413

from typing import Dict, Any, List

414

415

class WasmtimeDebugUtils:

416

"""Collection of utility functions for WebAssembly development and debugging"""

417

418

@staticmethod

419

def module_info(module: wasmtime.Module) -> Dict[str, Any]:

420

"""Extract comprehensive information about a WebAssembly module"""

421

info = {

422

"imports": [],

423

"exports": [],

424

"custom_sections": {}

425

}

426

427

# Analyze imports

428

for imp in module.imports:

429

info["imports"].append({

430

"module": imp.module,

431

"name": imp.name,

432

"type": str(imp.type),

433

"type_class": type(imp.type).__name__

434

})

435

436

# Analyze exports

437

for exp in module.exports:

438

info["exports"].append({

439

"name": exp.name,

440

"type": str(exp.type),

441

"type_class": type(exp.type).__name__

442

})

443

444

# Check for common custom sections

445

common_sections = ["name", "producers", "target_features", "linking"]

446

for section_name in common_sections:

447

sections = module.custom_sections(section_name)

448

if sections:

449

info["custom_sections"][section_name] = f"{len(sections)} section(s)"

450

451

return info

452

453

@staticmethod

454

def benchmark_function(func: wasmtime.Func, store: wasmtime.Store,

455

args: List[Any], iterations: int = 1000) -> Dict[str, float]:

456

"""Benchmark a WebAssembly function"""

457

print(f"Benchmarking function with {iterations} iterations...")

458

459

# Warmup

460

for _ in range(10):

461

func(store, *args)

462

463

# Actual benchmark

464

start_time = time.perf_counter()

465

for _ in range(iterations):

466

result = func(store, *args)

467

end_time = time.perf_counter()

468

469

total_time = end_time - start_time

470

avg_time = total_time / iterations

471

472

return {

473

"total_time_seconds": total_time,

474

"average_time_microseconds": avg_time * 1_000_000,

475

"calls_per_second": iterations / total_time,

476

"iterations": iterations,

477

"last_result": result

478

}

479

480

@staticmethod

481

def create_test_wat(function_name: str, operation: str) -> str:

482

"""Generate test WAT code for common operations"""

483

templates = {

484

"add": f'''

485

(module

486

(func (export "{function_name}") (param i32 i32) (result i32)

487

local.get 0

488

local.get 1

489

i32.add))

490

''',

491

492

"factorial": f'''

493

(module

494

(func (export "{function_name}") (param i32) (result i32)

495

(local i32)

496

i32.const 1

497

local.set 1

498

(loop

499

local.get 0

500

i32.const 1

501

i32.le_s

502

if

503

local.get 1

504

return

505

end

506

local.get 1

507

local.get 0

508

i32.mul

509

local.set 1

510

local.get 0

511

i32.const 1

512

i32.sub

513

local.set 0

514

br 0)))

515

''',

516

517

"memory_test": f'''

518

(module

519

(memory (export "memory") 1)

520

(func (export "{function_name}") (param i32 i32)

521

local.get 0

522

local.get 1

523

i32.store))

524

'''

525

}

526

527

return templates.get(operation, templates["add"])

528

529

@staticmethod

530

def validate_and_analyze_wat(wat_code: str) -> Dict[str, Any]:

531

"""Validate WAT code and provide analysis"""

532

try:

533

# Convert WAT to WASM

534

wasm_bytes = wasmtime.wat2wasm(wat_code)

535

536

# Create module for analysis

537

engine = wasmtime.Engine()

538

module = wasmtime.Module(engine, wasm_bytes)

539

540

analysis = {

541

"valid": True,

542

"wasm_size": len(wasm_bytes),

543

"module_info": WasmtimeDebugUtils.module_info(module),

544

"error": None

545

}

546

547

except wasmtime.WasmtimeError as e:

548

analysis = {

549

"valid": False,

550

"wasm_size": 0,

551

"module_info": None,

552

"error": str(e)

553

}

554

555

return analysis

556

557

# Example usage of utility functions

558

if __name__ == "__main__":

559

utils = WasmtimeDebugUtils()

560

561

# Test WAT validation

562

test_wat = utils.create_test_wat("test_add", "add")

563

analysis = utils.validate_and_analyze_wat(test_wat)

564

565

print("WAT Analysis:")

566

print(json.dumps(analysis, indent=2))

567

568

if analysis["valid"]:

569

# Create and benchmark the function

570

engine = wasmtime.Engine()

571

store = wasmtime.Store(engine)

572

wasm_bytes = wasmtime.wat2wasm(test_wat)

573

module = wasmtime.Module(engine, wasm_bytes)

574

instance = wasmtime.Instance(store, module, [])

575

576

add_func = instance.exports(store)["test_add"]

577

benchmark = utils.benchmark_function(add_func, store, [100, 200], 10000)

578

579

print("\nBenchmark Results:")

580

print(json.dumps(benchmark, indent=2))

581

582

# Test factorial function

583

factorial_wat = utils.create_test_wat("factorial", "factorial")

584

factorial_analysis = utils.validate_and_analyze_wat(factorial_wat)

585

586

if factorial_analysis["valid"]:

587

engine = wasmtime.Engine()

588

store = wasmtime.Store(engine)

589

wasm_bytes = wasmtime.wat2wasm(factorial_wat)

590

module = wasmtime.Module(engine, wasm_bytes)

591

instance = wasmtime.Instance(store, module, [])

592

593

factorial_func = instance.exports(store)["factorial"]

594

595

# Test factorial computation

596

for n in range(1, 8):

597

result = factorial_func(store, n)

598

print(f"{n}! = {result}")

599

```