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

memory.mddocs/

0

# Memory Management

1

2

Linear memory allocation, access, and manipulation supporting both regular and shared memory models. Provides comprehensive memory operations including growth, data transfer, multi-threading coordination, and direct memory access for high-performance WebAssembly applications.

3

4

## Capabilities

5

6

### Linear Memory

7

8

WebAssembly linear memory providing byte-addressable storage with dynamic growth capabilities, bounds checking, and direct data access for efficient communication between Python and WebAssembly code.

9

10

```python { .api }

11

class Memory:

12

def __init__(self, store: Store, ty: MemoryType):

13

"""

14

Create a new linear memory with specified type.

15

16

Parameters:

17

- store: Store for memory allocation context

18

- ty: Memory type specifying size limits

19

20

Raises:

21

WasmtimeError: If memory allocation fails

22

"""

23

24

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

25

"""

26

Get the memory type specification.

27

28

Parameters:

29

- store: Store context

30

31

Returns:

32

Memory type with current size limits

33

"""

34

35

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

36

"""

37

Grow memory by specified number of pages.

38

39

Parameters:

40

- store: Store context

41

- delta: Number of 64KB pages to add (must be non-negative)

42

43

Returns:

44

Previous memory size in pages

45

46

Raises:

47

WasmtimeError: If growth fails or exceeds maximum size

48

"""

49

50

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

51

"""

52

Get current memory size in pages.

53

54

Parameters:

55

- store: Store context

56

57

Returns:

58

Memory size in 64KB pages

59

"""

60

61

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

62

"""

63

Get current memory size in bytes.

64

65

Parameters:

66

- store: Store context

67

68

Returns:

69

Memory size in bytes

70

"""

71

72

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

73

"""

74

Get pointer to raw memory data.

75

76

Parameters:

77

- store: Store context

78

79

Returns:

80

Pointer to memory data (for advanced use with ctypes)

81

82

Warning:

83

Direct pointer access bypasses bounds checking

84

"""

85

86

def read(self, store: Store, start: int, stop: int) -> bytes:

87

"""

88

Read bytes from memory range.

89

90

Parameters:

91

- store: Store context

92

- start: Starting byte offset

93

- stop: Ending byte offset (exclusive)

94

95

Returns:

96

Bytes read from memory

97

98

Raises:

99

WasmtimeError: If range is out of bounds

100

"""

101

102

def write(self, store: Store, data: bytes, start: int = 0) -> None:

103

"""

104

Write bytes to memory starting at offset.

105

106

Parameters:

107

- store: Store context

108

- data: Bytes to write

109

- start: Starting byte offset (default: 0)

110

111

Raises:

112

WasmtimeError: If write would exceed memory bounds

113

"""

114

```

115

116

### Shared Memory

117

118

Multi-threaded shared memory supporting concurrent access from multiple WebAssembly instances, with proper synchronization primitives and cross-thread memory coordination.

119

120

```python { .api }

121

class SharedMemory:

122

def __init__(self, engine: Engine, ty: MemoryType):

123

"""

124

Create a new shared memory with specified type.

125

126

Parameters:

127

- engine: Engine for shared memory allocation

128

- ty: Memory type specifying size limits (must be shared-compatible)

129

130

Raises:

131

WasmtimeError: If shared memory creation fails or type incompatible

132

"""

133

134

def type(self) -> MemoryType:

135

"""

136

Get the shared memory type specification.

137

138

Returns:

139

Memory type with size limits and shared flag

140

"""

141

142

def as_memory(self, store: Store) -> Memory:

143

"""

144

Get a Memory view for use within a specific store.

145

146

Parameters:

147

- store: Store context for memory access

148

149

Returns:

150

Memory object providing access to shared memory

151

152

Note:

153

Multiple stores can have Memory views of the same SharedMemory

154

"""

155

```

156

157

## Usage Examples

158

159

### Basic Memory Operations

160

161

```python

162

import wasmtime

163

164

# Create memory type: 1-10 pages (64KB - 640KB)

165

limits = wasmtime.Limits(1, 10)

166

memory_type = wasmtime.MemoryType(limits)

167

168

# Create engine, store, and memory

169

engine = wasmtime.Engine()

170

store = wasmtime.Store(engine)

171

memory = wasmtime.Memory(store, memory_type)

172

173

# Check initial memory size

174

pages = memory.size(store)

175

bytes_size = memory.data_len(store)

176

print(f"Initial memory: {pages} pages ({bytes_size} bytes)")

177

178

# Write data to memory

179

message = b"Hello from Python!"

180

memory.write(store, message, 0)

181

182

# Read data back

183

read_data = memory.read(store, 0, len(message))

184

print(f"Read from memory: {read_data.decode('utf-8')}")

185

186

# Grow memory

187

old_size = memory.grow(store, 2) # Add 2 pages (128KB)

188

new_size = memory.size(store)

189

print(f"Memory grown from {old_size} to {new_size} pages")

190

```

191

192

### Memory with WebAssembly Module

193

194

```python

195

import wasmtime

196

197

# WebAssembly module that uses memory

198

wasm_bytes = wasmtime.wat2wasm('''

199

(module

200

(memory (export "memory") 1 10)

201

(func (export "write_hello") (param i32)

202

;; Write "Hello" starting at given offset

203

local.get 0

204

i32.const 72 ;; 'H'

205

i32.store8

206

local.get 0

207

i32.const 1

208

i32.add

209

i32.const 101 ;; 'e'

210

i32.store8

211

local.get 0

212

i32.const 2

213

i32.add

214

i32.const 108 ;; 'l'

215

i32.store8

216

local.get 0

217

i32.const 3

218

i32.add

219

i32.const 108 ;; 'l'

220

i32.store8

221

local.get 0

222

i32.const 4

223

i32.add

224

i32.const 111 ;; 'o'

225

i32.store8)

226

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

227

local.get 0

228

i32.load8_u)

229

)

230

''')

231

232

engine = wasmtime.Engine()

233

store = wasmtime.Store(engine)

234

module = wasmtime.Module(engine, wasm_bytes)

235

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

236

237

# Get exported memory and functions

238

exports = instance.exports(store)

239

memory = exports["memory"]

240

write_hello = exports["write_hello"]

241

read_byte = exports["read_byte"]

242

243

# Call WebAssembly function to write to memory

244

write_hello(store, 10) # Write "Hello" starting at offset 10

245

246

# Read from memory using Python

247

hello_bytes = memory.read(store, 10, 15)

248

print(f"WebAssembly wrote: {hello_bytes.decode('utf-8')}")

249

250

# Read individual bytes using WebAssembly function

251

for i in range(5):

252

byte_val = read_byte(store, 10 + i)

253

print(f"Byte at {10 + i}: {byte_val} ('{chr(byte_val)}')")

254

```

255

256

### Shared Memory for Multi-threading

257

258

```python

259

import wasmtime

260

import threading

261

import time

262

263

# Create shared memory configuration

264

config = wasmtime.Config()

265

config.wasm_threads(True) # Enable threads support

266

engine = wasmtime.Engine(config)

267

268

# Create shared memory: 1-5 pages, shared

269

limits = wasmtime.Limits(1, 5)

270

memory_type = wasmtime.MemoryType(limits)

271

shared_memory = wasmtime.SharedMemory(engine, memory_type)

272

273

def worker_thread(thread_id: int):

274

"""Worker thread that accesses shared memory"""

275

# Each thread needs its own store

276

store = wasmtime.Store(engine)

277

278

# Get memory view for this store

279

memory = shared_memory.as_memory(store)

280

281

# Write thread-specific data

282

message = f"Thread {thread_id} was here!".encode('utf-8')

283

offset = thread_id * 32 # Each thread writes to different offset

284

memory.write(store, message, offset)

285

286

print(f"Thread {thread_id} wrote to offset {offset}")

287

288

# Start multiple threads

289

threads = []

290

for i in range(3):

291

thread = threading.Thread(target=worker_thread, args=(i,))

292

threads.append(thread)

293

thread.start()

294

295

# Wait for all threads to complete

296

for thread in threads:

297

thread.join()

298

299

# Read all data from main thread

300

main_store = wasmtime.Store(engine)

301

main_memory = shared_memory.as_memory(main_store)

302

303

print("Reading results from shared memory:")

304

for i in range(3):

305

offset = i * 32

306

# Read up to 32 bytes or until null terminator

307

data = main_memory.read(main_store, offset, offset + 32)

308

# Find null terminator if present

309

null_pos = data.find(b'\x00')

310

if null_pos != -1:

311

data = data[:null_pos]

312

print(f"Thread {i} data: {data.decode('utf-8')}")

313

```

314

315

### Memory Growth and Bounds Checking

316

317

```python

318

import wasmtime

319

320

# Create memory with tight limits for demonstration

321

limits = wasmtime.Limits(1, 3) # 1-3 pages (64KB - 192KB)

322

memory_type = wasmtime.MemoryType(limits)

323

324

engine = wasmtime.Engine()

325

store = wasmtime.Store(engine)

326

memory = wasmtime.Memory(store, memory_type)

327

328

# Fill initial page with data

329

page_size = 64 * 1024 # 64KB

330

test_data = b'A' * (page_size - 100) # Fill most of first page

331

memory.write(store, test_data, 0)

332

333

print(f"Initial memory: {memory.size(store)} pages")

334

335

# Try to write beyond current memory - should fail

336

try:

337

memory.write(store, b"This will fail", page_size + 1000)

338

except wasmtime.WasmtimeError as e:

339

print(f"Expected error: {e}")

340

341

# Grow memory and try again

342

old_size = memory.grow(store, 1) # Add 1 page

343

print(f"Memory grown from {old_size} to {memory.size(store)} pages")

344

345

# Now write to second page - should succeed

346

memory.write(store, b"Second page data", page_size + 100)

347

second_page_data = memory.read(store, page_size + 100, page_size + 116)

348

print(f"Second page contains: {second_page_data.decode('utf-8')}")

349

350

# Try to grow beyond maximum - should fail

351

try:

352

memory.grow(store, 5) # Would exceed 3-page maximum

353

except wasmtime.WasmtimeError as e:

354

print(f"Growth limit reached: {e}")

355

```

356

357

### Direct Memory Access with ctypes

358

359

```python

360

import wasmtime

361

import ctypes

362

363

# Create memory

364

engine = wasmtime.Engine()

365

store = wasmtime.Store(engine)

366

limits = wasmtime.Limits(1)

367

memory_type = wasmtime.MemoryType(limits)

368

memory = wasmtime.Memory(store, memory_type)

369

370

# Get direct pointer to memory (advanced usage)

371

ptr = memory.data_ptr(store)

372

size = memory.data_len(store)

373

374

# Create ctypes array from memory pointer

375

# WARNING: This bypasses WebAssembly bounds checking!

376

memory_array = (ctypes.c_ubyte * size).from_address(ptr)

377

378

# Write using ctypes (very fast, but unsafe)

379

test_string = b"Direct memory access"

380

for i, byte in enumerate(test_string):

381

memory_array[i] = byte

382

383

# Read back using normal memory API

384

read_data = memory.read(store, 0, len(test_string))

385

print(f"Direct write result: {read_data.decode('utf-8')}")

386

387

# Structure overlay example

388

class DataStruct(ctypes.Structure):

389

_fields_ = [

390

("magic", ctypes.c_uint32),

391

("version", ctypes.c_uint16),

392

("flags", ctypes.c_uint16),

393

("data_size", ctypes.c_uint32)

394

]

395

396

# Overlay structure on memory (at offset 100)

397

struct_ptr = ptr + 100

398

data_struct = DataStruct.from_address(struct_ptr)

399

400

# Write structured data

401

data_struct.magic = 0x12345678

402

data_struct.version = 1

403

data_struct.flags = 0b1010

404

data_struct.data_size = 1024

405

406

# Read back using memory API

407

struct_bytes = memory.read(store, 100, 100 + ctypes.sizeof(DataStruct))

408

magic_bytes = struct_bytes[:4]

409

magic_value = int.from_bytes(magic_bytes, 'little')

410

print(f"Magic value: 0x{magic_value:08x}")

411

```

412

413

### Memory Debugging and Inspection

414

415

```python

416

import wasmtime

417

418

def dump_memory(memory: wasmtime.Memory, store: wasmtime.Store,

419

start: int = 0, length: int = 256, width: int = 16):

420

"""Debug utility to dump memory contents in hex format"""

421

data = memory.read(store, start, start + length)

422

423

print(f"Memory dump from 0x{start:04x} to 0x{start + length:04x}:")

424

for i in range(0, len(data), width):

425

# Address

426

addr = start + i

427

print(f"{addr:04x}: ", end="")

428

429

# Hex bytes

430

line_data = data[i:i + width]

431

for j, byte in enumerate(line_data):

432

print(f"{byte:02x} ", end="")

433

434

# Padding for incomplete lines

435

for j in range(len(line_data), width):

436

print(" ", end="")

437

438

# ASCII representation

439

print(" |", end="")

440

for byte in line_data:

441

if 32 <= byte <= 126: # Printable ASCII

442

print(chr(byte), end="")

443

else:

444

print(".", end="")

445

print("|")

446

447

# Example usage

448

engine = wasmtime.Engine()

449

store = wasmtime.Store(engine)

450

limits = wasmtime.Limits(1)

451

memory = wasmtime.Memory(store, wasmtime.MemoryType(limits))

452

453

# Write some test data

454

test_data = b"Hello, WebAssembly World!\x00\x01\x02\x03\xff\xfe\xfd"

455

memory.write(store, test_data, 0)

456

457

# Dump memory contents

458

dump_memory(memory, store, 0, 64)

459

```