Skip to content

Commit 82279e5

Browse files
authored
Merge pull request #19 from multikernel/iflet-and-map-field-compound
Add `if (var x = expr)` and `map[k].field op= rhs`
2 parents 4031506 + 198fe92 commit 82279e5

32 files changed

Lines changed: 1154 additions & 256 deletions

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ KernelScript addresses these problems through revolutionary language features:
6262

6363
**Zero-boilerplate shared state** - Maps are automatically accessible across all programs as regular global variables in a programming language
6464

65+
**Ergonomic map idioms** - Declaration-as-condition (`if (var s = m[k]) { s.field = ... }`) and compound assignment on map indices (`m[k].count += 1`) compile down to a single presence-checked lookup with in-place mutation, no manual write-back
66+
6567
**Builtin kfunc support** - Define full-privilege kernel functions that eBPF programs can call directly, automatically generating kernel modules and BTF registrations
6668

6769
**Unified error handling** - C-style integer throw/catch works seamlessly in both eBPF and userspace contexts, unlike complex Result types
@@ -213,16 +215,38 @@ fn handle_action(action: FilterAction) -> xdp_action {
213215
}
214216
}
215217
216-
// Map lookup and update patterns
218+
// Map lookup and update patterns — declaration-as-condition binds
219+
// `count` only inside the truthy branch; one map lookup, no extra
220+
// presence-check variable.
217221
fn lookup_or_create(ip: IpAddress) -> Counter {
218-
var count = connection_count[ip]
219-
if (count != none) {
222+
if (var count = connection_count[ip]) {
220223
return count // Entry exists
221224
} else {
222225
connection_count[ip] = 1 // Create new entry
223226
return 1
224227
}
225228
}
229+
230+
// Declaration-as-condition: bind only inside the truthy branch.
231+
// For struct-valued maps, the bound name is the lookup pointer, so
232+
// field access auto-derefs and the generated eBPF performs in-place
233+
// mutation against the underlying entry — no write-back needed.
234+
pin var ip_stats : hash<IpAddress, PacketInfo>(1024)
235+
236+
@helper
237+
fn record_packet(ip: IpAddress, size: PacketSize) {
238+
if (var stats = ip_stats[ip]) {
239+
stats.size = size
240+
} else {
241+
ip_stats[ip] = PacketInfo { src_ip: ip, dst_ip: 0, protocol: 0, size: size }
242+
}
243+
}
244+
245+
// Compound assignment indexes into struct-valued maps directly:
246+
@helper
247+
fn bump_size(ip: IpAddress, delta: PacketSize) {
248+
ip_stats[ip].size += delta // emits a presence-checked ptr->size += delta
249+
}
226250
```
227251

228252
### Multi-Program Coordination

0 commit comments

Comments
 (0)