waclay 0.2.1

Runtime-agnostic WebAssembly Component Model implementation
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# Architecture Guide


This document provides a comprehensive overview of `wasm_component_layer`'s architecture, design decisions, and implementation details. It's intended for developers who want to understand how the library works internally, extend its functionality, or contribute to its development.

## Overview


`wasm_component_layer` implements the [WebAssembly Component Model](https://github.com/WebAssembly/component-model) specification atop any WebAssembly runtime backend. The library is structured as a layered architecture:

```
┌─────────────────────────────────────┐
│         WASM Runtime with Component |
|               Model Support         │
├─────────────────────────────────────┤
│       wasm_component_layer          │
│   ┌─────────────────────────────┐   │
│   │    Component Model Layer    │   │
│   │  (Types, Values, Functions) │   │
│   ├─────────────────────────────┤   │
│   │     Canonical ABI Layer     │   │
│   │   (Lifting/Lowering Logic)  │   │
│   ├─────────────────────────────┤   │
│   │   Runtime Abstraction Layer │   │
│   │    (wasm_runtime_layer)     │   │
│   └─────────────────────────────┘   │
├─────────────────────────────────────┤
│       WebAssembly Runtime           │
│   (wasmi, wasmtime, etc.)           │
└─────────────────────────────────────┘
```

## Core Components


### Component Model Layer


This layer implements the component model types and values:

#### Types System (`types.rs`)


The type system is the foundation of the component model. All types implement structural equality as mandated by the specification.

**Key Design Decisions:**
- All types are immutable and cheaply cloneable using `Arc`
- Complex types (records, variants, etc.) store their constituent types in sorted order for efficient comparison
- Resource types are special - they can be abstract (uninstantiated) or concrete (instantiated/host)

**Type Hierarchy:**
```
ValueType (enum)
├── Primitive types (Bool, S8, U8, ..., String, Char)
├── List(ListType)
├── Record(RecordType)
├── Tuple(TupleType)
├── Variant(VariantType)
├── Enum(EnumType)
├── Option(OptionType)
├── Result(ResultType)
├── Flags(FlagsType)
├── Own(ResourceType)
└── Borrow(ResourceType)
```

**Resource Type States:**
- `Abstract`: Guest resource type that hasn't been instantiated yet
- `Instantiated`: Guest resource type tied to a specific instance
- `Host`: Host-defined resource type with optional destructor

#### Values System (`values.rs`)


Values represent runtime data that can be passed between host and guest.

**Specialized Storage:**
For performance, lists of primitive types use specialized storage:

```rust
enum ListSpecialization {
    Bool(Arc<[bool]>),
    S8(Arc<[i8]>),
    U8(Arc<[u8]>),
    // ... other primitives
    Other(Vec<Value>),  // For complex types
}
```

This avoids boxing each primitive value individually.

**Resource Ownership:**
Resources use reference counting for ownership tracking:
- `ResourceOwn`: Owned resource with destructor
- `ResourceBorrow`: Borrowed resource with lifetime tracking

### Canonical ABI Layer (`abi.rs`, `func.rs`)


Implements the [Canonical ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md) for lifting/lowering values between host and guest representations.

#### Function Calling Architecture


Function calls go through several phases:

1. **Host Call Path:**
   ```
   User Code → TypedFunc → Func::call → FuncBindgen → ABI Instructions → WASM Call
   ```

2. **Guest Call Path:**
   ```
   WASM → Trampoline → Func::call_from_guest → FuncBindgen → ABI Instructions → Host Function
   ```

#### ABI Instruction Set


The `Instruction` enum represents the canonical ABI operations:

```rust
enum Instruction {
    // Argument/result handling
    GetArg { nth: usize },
    Return { amt: usize, func: Function },

    // Memory operations
    I32Load { offset: usize },
    I32Store { offset: usize },
    // ... many more

    // Type operations
    RecordLower { record: Record, ty: TypeId },
    RecordLift { record: Record, ty: TypeId },
    ListLower { element: Type, .. },
    // ... etc

    // Control flow
    CallWasm { name: Option<String>, sig: WasmSignature },
    CallInterface { func: Function },
}
```

#### Bindgen Pattern


`FuncBindgen` implements the `Bindgen` trait, which processes ABI instructions:

```rust
trait Bindgen {
    type Operand = Value;
    fn emit(&mut self, resolve: &Resolve, inst: &Instruction, operands: &mut Vec<Self::Operand>, results: &mut Vec<Self::Operand>) -> Result<()>;
}
```

This design allows the same ABI logic to work for both lifting (guest→host) and lowering (host→guest).

### Runtime Abstraction Layer


The library uses `wasm_runtime_layer` to abstract over different WebAssembly runtimes. This provides:

- `Engine`: Compilation environment
- `Store`: Runtime state management
- `Module`: Compiled WebAssembly module
- `Instance`: Instantiated module
- `Func`: Callable function
- `Memory`: Linear memory

## Component Loading and Instantiation


### Component Structure


A `Component` represents a parsed WebAssembly component:

```rust
struct ComponentInner {
    // Type information
    export_types: ComponentTypes,
    import_types: ComponentTypes,

    // Runtime modules and linking
    modules: FxHashMap<StaticModuleIndex, ModuleTranslation>,
    generated_trampolines: FxHashMap<TrampolineIndex, GeneratedTrampoline>,

    // Resource management
    resource_map: Vec<TypeResourceTableIndex>,

    // WIT resolution
    resolve: Resolve,
    world_id: Id<World>,
}
```

### Instantiation Process


1. **Parse Component:** Decode WIT and WASM bytes
2. **Translate Modules:** Convert component to core WASM modules
3. **Generate Types:** Create type information for exports/imports
4. **Extract Initializers:** Process component initialization logic
5. **Link and Instantiate:** Resolve imports and create instances

### Linking Architecture


The `Linker` manages import resolution:

```rust
struct Linker {
    root: LinkerInstance,
    instances: FxHashMap<InterfaceIdentifier, LinkerInstance>,
}

struct LinkerInstance {
    functions: FxHashMap<Arc<str>, Func>,
    resources: FxHashMap<Arc<str>, ResourceType>,
}
```

This allows hierarchical import organization matching the component model design.

## Resource Management


### Resource Tables


Resources are managed through tables that track ownership and borrowing:

```rust
struct HandleTable {
    array: Slab<HandleElement>,
    destructor: Option<Func>,
}

struct HandleElement {
    rep: i32,           // Guest representation
    own: bool,          // Owned or borrowed?
    lend_count: i32,    // Number of active borrows
}
```

### Ownership Semantics


- **Owned Resources:** Can be transferred between host/guest, have destructors
- **Borrowed Resources:** Temporary access, must be returned before owner is dropped
- **Reference Counting:** Prevents use-after-free and double-free

### Host vs Guest Resources


- **Host Resources:** Backed by Rust values, stored in `Slab<Box<dyn Any>>`
- **Guest Resources:** Opaque handles managed by guest code

## Type System Deep Dive


### Structural Equality


All component model types must support structural equality. This is implemented through:

1. **Sorted Storage:** Complex types store fields in sorted order
2. **Recursive Comparison:** Types compare their structure, not identity
3. **Arc-based Sharing:** Types can be shared efficiently

### Type Interning


Types are not interned globally - each component has its own type universe. This simplifies the implementation but means identical types from different components are not equal.

### Resource Type Instantiation


Abstract resource types become concrete during instantiation:

```rust
// Before instantiation
ResourceType::Abstract { id: 0, component: 123 }

// After instantiation
ResourceType::Instantiated { id: 0, instance: 456 }
```

## Memory Management


### Canonical ABI Memory Layout


The Canonical ABI defines how complex types are laid out in linear memory:

- **Alignment:** Types have alignment requirements
- **Size Calculation:** Static size computation for memory allocation
- **Little-Endian:** All data is stored in little-endian byte order

### Memory Operations


Memory access is abstracted through the `Bindgen` trait:

```rust
fn load<B: Blittable>(&self, offset: usize) -> Result<B>
fn store<B: Blittable>(&mut self, offset: usize, value: B) -> Result<()>
```

The `Blittable` trait handles primitive type serialization.

## Error Handling


The library uses `anyhow::Error` for flexible error handling. Specific error types include:

- `FuncError`: Function call failures with context
- Type mismatch errors
- Resource lifetime violations
- ABI validation failures

## Performance Characteristics


### Optimizations


1. **Specialized Lists:** Primitive lists avoid individual boxing
2. **Arc-based Cloning:** Cheap type/value duplication
3. **Direct Memory Access:** Blittable types bypass serialization
4. **Trampoline Reuse:** Generated trampolines are cached

### Trade-offs


1. **Memory Usage:** Arc overhead for all types
2. **Allocation Pressure:** Many small allocations for complex types
3. **Validation Cost:** Full type checking on every operation

## Extension Points


### Adding New Types


To add a new component model type:

1. Add variant to `ValueType` enum
2. Implement `Display` and `Debug`
3. Add to `ValueType::from_component` conversion
4. Implement ABI lifting/lowering instructions
5. Add to `ComponentList` trait if needed

### Runtime Backend Integration


To support a new WebAssembly runtime:

1. Implement `wasm_runtime_layer::backend::WasmEngine`
2. Ensure all required traits are implemented
3. Test with existing examples

### Feature Extensions


Common extension points:

- **String Transcoding:** Support for different string encodings
- **Subtyping:** Type coercion and subtyping rules
- **Async Functions:** Support for async component functions
- **Streaming:** Support for streams and futures

## Testing Strategy


### Unit Tests


- Type system correctness
- ABI instruction validation
- Resource lifetime management

### Integration Tests


- End-to-end component instantiation
- Cross-runtime compatibility
- Example validation

### Fuzzing


ABI instruction sequences are fuzzed to ensure robustness.

## Future Directions


### Planned Features


- String transcoding support
- Component model subtyping
- Async function support
- Enhanced debugging tools

### Architecture Improvements


- Type interning for memory efficiency
- JIT compilation of ABI sequences
- Parallel instantiation
- Advanced optimization passes

## Contributing Guidelines


### Code Organization


- `lib.rs`: Main API and documentation
- `types.rs`: Type system implementation
- `values.rs`: Value representations
- `func.rs`: Function calling and ABI
- `abi.rs`: Canonical ABI implementation
- `*.rs`: Supporting utilities

### Testing Requirements


- All new features must have comprehensive tests
- Performance regressions must be justified
- ABI compatibility must be maintained

### Documentation Standards


- All public APIs must have documentation
- Complex algorithms need explanatory comments
- Architecture decisions should be documented

This architecture provides a solid foundation for WebAssembly component model implementation while remaining extensible for future enhancements.

---

> **⚠️ Warning: Documentation**
>
> This documentation was completely refined by AI and may contain inaccuracies, errors, or incomplete information. Please use it as a reference but verify critical details against the actual codebase. If you find any useful corrections, improvements, or additional content that would benefit other users, please submit a pull request to help improve this documentation for the community.