Skip to content

Commit a63eb0f

Browse files
committed
Refactor map declarations to use new syntax. Update all instances of map<K, V> to var name: Type<K, V>(size) across documentation, examples, and tests for consistency and clarity.
1 parent 49d78d7 commit a63eb0f

39 files changed

+275
-278
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,16 @@ Built-in support for all eBPF map types:
132132

133133
```kernelscript
134134
// Pinned maps persist across program restarts
135-
pin map<IpAddress, Counter> connection_count : HashMap(1024)
135+
pin var connection_count : HashMap<IpAddress, Counter>(1024)
136136
137137
// Per-CPU maps for better performance
138-
map<u32, u64> cpu_stats : PercpuArray(256)
138+
var cpu_stats : PercpuArray<u32, u64>(256)
139139
140140
// LRU maps for automatic eviction
141-
map<IpAddress, PacketInfo> recent_packets : LruHash(1000)
141+
var recent_packets : LruHash<IpAddress, PacketInfo>(1000)
142142
143143
// Ring buffers for event streaming
144-
pin map<u32, u8> event_log : RingBuffer(65536)
144+
pin var event_log : RingBuffer<u32, u8>(65536)
145145
```
146146

147147
### Functions and Helpers
@@ -205,7 +205,7 @@ KernelScript can coordinate multiple eBPF programs:
205205

206206
```kernelscript
207207
// Shared map between programs
208-
pin map<u32, u32> shared_counter : HashMap(1024)
208+
pin var shared_counter : HashMap<u32, u32>(1024)
209209
210210
// XDP program increments counter
211211
@xdp fn packet_counter(ctx: *xdp_md) -> xdp_action {

SPEC.md

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ u8[64] // 64-byte buffer
2525
u32[16] // 16 u32 values
2626
2727
// Simple map declarations
28-
map<u32, u64> counters : Array(256)
29-
map<IpAddress, PacketStats> flows : HashMap(1024)
28+
var counters : Array<u32, u64>(256)
29+
var flows : HashMap<IpAddress, PacketStats>(1024)
3030
3131
// No complex template metaprogramming - just practical, concrete types
3232
```
@@ -43,7 +43,7 @@ KernelScript uses a simple and clear scoping model that eliminates ambiguity:
4343
```kernelscript
4444
// Shared resources (accessible by both kernel and userspace)
4545
config system { debug: bool = false }
46-
map<u32, u64> counters : Array(256)
46+
var counters : Array<u32, u64>(256)
4747
4848
// Kernel-shared functions (accessible by all eBPF programs)
4949
@helper
@@ -137,12 +137,12 @@ fn main() -> i32 {
137137
### 2.1 Keywords
138138
```
139139
program fn var const config local
140-
map pin type struct enum if else
141-
for while loop break continue return import
142-
export pub priv static unsafe where impl
143-
true false null and or not in
144-
as is try catch throw defer go
145-
delete match test
140+
pin type struct enum if else for
141+
while loop break continue return import export
142+
pub priv static unsafe where impl true
143+
false null and or not in as
144+
is try catch throw defer go delete
145+
match test
146146
```
147147

148148
**Note**: The `pin` keyword is used for both maps and global variables to enable filesystem persistence.
@@ -480,7 +480,7 @@ struct PinnedGlobals {
480480
481481
// Single-entry pinned map
482482
@flags(BPF_F_NO_PREALLOC)
483-
pin map<u32, PinnedGlobals> __pinned_globals : Array(1)
483+
pin var __pinned_globals : Array<u32, PinnedGlobals>(1)
484484
485485
// Access wrappers (transparent to user):
486486
// packet_count access becomes: __pinned_globals[0].packet_count
@@ -536,7 +536,7 @@ fn main() -> i32 {
536536

537537
| Feature | Global Variables | Pinned Global Variables | Maps | Configs |
538538
|---------|------------------|-------------------------|------|---------|
539-
| **Syntax** | `var name: type = value` | `pin var name: type = value` | `[pin] [@flags(...)] map<K,V> name : Type(size)` | `config name { field: type = value }` |
539+
| **Syntax** | `var name: type = value` | `pin var name: type = value` | `[pin] [@flags(...)] var name : Type<K,V>(size)` | `config name { field: type = value }` |
540540
| **Use Case** | Simple shared state | Persistent simple state | Complex data structures | Structured configuration |
541541
| **Access** | Direct variable access | Direct variable access | Key-value lookup | Dotted field access |
542542
| **Performance** | Fastest | Fast (single map lookup) | Medium | Fastest |
@@ -561,7 +561,7 @@ config monitoring {
561561
packets_processed: u64 = 0,
562562
}
563563
564-
map<u32, PacketStats> global_stats : HashMap(1024)
564+
var global_stats : HashMap<u32, PacketStats>(1024)
565565
566566
// Userspace types
567567
struct PacketStats {
@@ -1356,7 +1356,7 @@ struct tcp_congestion_ops {
13561356
}
13571357
13581358
// Initialize shared state before registration
1359-
map<u32, BbrState> connection_state : HashMap(1024)
1359+
var connection_state : HashMap<u32, BbrState>(1024)
13601360
13611361
// Implement struct_ops using impl block syntax
13621362
@struct_ops("tcp_congestion_ops")
@@ -2031,7 +2031,7 @@ fn ebpf_function_parameters() {
20312031
#### 4.6.7 Map Integration with Pointers
20322032

20332033
```kernelscript
2034-
map<FlowKey, FlowData> flow_map : HashMap(1024)
2034+
var flow_map : HashMap<FlowKey, FlowData>(1024)
20352035
20362036
@helper
20372037
fn map_pointer_operations(flow_key: FlowKey) {
@@ -2087,7 +2087,7 @@ fn bounds_safety_example(ctx: *xdp_md) -> xdp_action {
20872087

20882088
### 5.1 Map Declaration Syntax
20892089
```ebnf
2090-
map_declaration = [ "pin" ] [ "@flags" "(" flag_expression ")" ] "map" "<" key_type "," value_type ">" identifier ":" map_type "(" map_config ")"
2090+
map_declaration = [ "pin" ] [ "@flags" "(" flag_expression ")" ] "var" identifier ":" map_type "<" key_type "," value_type ">" "(" map_config ")"
20912091
20922092
map_type = "HashMap" | "Array" | "ProgArray" | "PerCpuHash" | "PerCpuArray" |
20932093
"LruHash" | "RingBuffer" | "PerfEvent" | "StackTrace"
@@ -2115,11 +2115,11 @@ Map flags can be specified using the `@flags` attribute:
21152115
```kernelscript
21162116
// Map with flags
21172117
@flags(BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU)
2118-
map<u32, PacketData> dynamic_cache : HashMap(1024)
2118+
var dynamic_cache : HashMap<u32, PacketData>(1024)
21192119
21202120
// Pinned map with flags
21212121
@flags(BPF_F_NO_PREALLOC)
2122-
pin map<u32, FlowData> persisted_flows : HashMap(2048)
2122+
pin var persisted_flows : HashMap<u32, FlowData>(2048)
21232123
```
21242124

21252125
**Supported flags:**
@@ -2136,10 +2136,10 @@ pin map<u32, FlowData> persisted_flows : HashMap(2048)
21362136
Global maps are declared at the global scope and are automatically shared between all eBPF programs.
21372137

21382138
**Map Declaration Syntax:**
2139-
- `map<K,V> name : Type(size)` - Local map (program-specific)
2140-
- `pin map<K,V> name : Type(size)` - Pinned map (persisted to filesystem)
2141-
- `@flags(...) map<K,V> name : Type(size)` - Map with specific flags
2142-
- `@flags(...) pin map<K,V> name : Type(size)` - Pinned map with flags
2139+
- `var name : Type<K,V>(size)` - Local map (program-specific)
2140+
- `pin var name : Type<K,V>(size)` - Pinned map (persisted to filesystem)
2141+
- `@flags(...) var name : Type<K,V>(size)` - Map with specific flags
2142+
- `@flags(...) pin var name : Type<K,V>(size)` - Pinned map with flags
21432143

21442144
**Automatic Path Generation:**
21452145
Pinned maps are automatically stored at `/sys/fs/bpf/<PROJECT_NAME>/maps/<MAP_NAME>`.
@@ -2148,16 +2148,16 @@ Pinned maps are automatically stored at `/sys/fs/bpf/<PROJECT_NAME>/maps/<MAP_NA
21482148
// Global maps - automatically shared between all programs
21492149
21502150
// Pinned maps - persisted to filesystem (/sys/fs/bpf/<PROJECT>/maps/<NAME>)
2151-
pin map<FlowKey, FlowStats> global_flows : HashMap(10000)
2152-
pin map<u32, InterfaceStats> interface_stats : Array(256)
2153-
pin map<SecurityEvent> security_events : RingBuffer(1024 * 1024)
2151+
pin var global_flows : HashMap<FlowKey, FlowStats>(10000)
2152+
pin var interface_stats : Array<u32, InterfaceStats>(256)
2153+
pin var security_events : RingBuffer<SecurityEvent>(1024 * 1024)
21542154
21552155
// Non-pinned maps - shared during runtime but not persisted
2156-
map<u32, TempData> session_cache : HashMap(512)
2156+
var session_cache : HashMap<u32, TempData>(512)
21572157
21582158
// Maps with flags
21592159
@flags(BPF_F_NO_PREALLOC)
2160-
pin map<ConfigKey, ConfigValue> global_config : Array(64)
2160+
pin var global_config : Array<ConfigKey, ConfigValue>(64)
21612161
21622162
// Program 1: Can access all global maps
21632163
@xdp
@@ -2234,8 +2234,8 @@ fn security_analyzer(ctx: LsmContext) -> i32 {
22342234

22352235
```kernelscript
22362236
// Global maps - accessible by all eBPF programs
2237-
pin map<u32, GlobalCounter> global_counters : Array(256)
2238-
pin map<Event> event_stream : RingBuffer(1024 * 1024)
2237+
pin var global_counters : Array<u32, GlobalCounter>(256)
2238+
pin var event_stream : RingBuffer<Event>(1024 * 1024)
22392239
22402240
@kprobe("sys_read")
22412241
fn producer(fd: u32, buf: *u8, count: usize) -> i32 {
@@ -2274,15 +2274,15 @@ fn consumer(fd: u32, buf: *u8, count: usize) -> i32 {
22742274
### 5.4 Map Examples
22752275
```kernelscript
22762276
// Global maps accessible by all programs
2277-
pin map<u32, PacketStats> packet_stats : HashMap(1024)
2277+
pin var packet_stats : HashMap<u32, PacketStats>(1024)
22782278
2279-
pin map<u32, u64> counters : PerCpuArray(256)
2279+
pin var counters : PerCpuArray<u32, u64>(256)
22802280
2281-
pin map<FlowKey, FlowInfo> active_flows : LruHash(10000)
2281+
pin var active_flows : LruHash<FlowKey, FlowInfo>(10000)
22822282
2283-
pin map<PacketEvent> events : RingBuffer(1024 * 1024)
2283+
pin var events : RingBuffer<PacketEvent>(1024 * 1024)
22842284
2285-
pin map<ConfigKey, ConfigValue> config_map : Array(16)
2285+
pin var config_map : Array<ConfigKey, ConfigValue>(16)
22862286
22872287
@xdp
22882288
fn simple_monitor(ctx: *xdp_md) -> xdp_action {
@@ -2373,7 +2373,7 @@ fn packet_counter(ctx: *xdp_md) -> xdp_action {
23732373
}
23742374
23752375
// Map operations with compound assignment
2376-
map<u32, FlowStats> flow_stats : HashMap(1024)
2376+
var flow_stats : HashMap<u32, FlowStats>(1024)
23772377
23782378
@helper
23792379
fn update_flow_stats(flow_id: u32, packet_size: u32) {
@@ -3196,11 +3196,11 @@ fn main() -> i32 {
31963196
### 9.2 Top-Level Userspace Coordination with Global Maps
31973197
```kernelscript
31983198
// Global maps (accessible from all programs and userspace)
3199-
pin map<FlowKey, FlowStats> global_flows : HashMap(10000)
3199+
pin var global_flows : HashMap<FlowKey, FlowStats>(10000)
32003200
3201-
pin map<Event> global_events : RingBuffer(1024 * 1024)
3201+
pin var global_events : RingBuffer<Event>(1024 * 1024)
32023202
3203-
pin map<ConfigKey, ConfigValue> global_config : Array(64)
3203+
pin var global_config : Array<ConfigKey, ConfigValue>(64)
32043204
32053205
// Multiple eBPF programs working together
32063206
@xdp fn network_monitor(ctx: *xdp_md) -> xdp_action {
@@ -3415,7 +3415,7 @@ fn safe_userspace_access(data: *u8, len: u32) -> u8 {
34153415
The compiler transparently uses eBPF's dynamic pointer (dynptr) APIs when beneficial, without exposing complexity to the programmer.
34163416

34173417
```kernelscript
3418-
map<Event> event_log : RingBuffer(1024 * 1024)
3418+
var event_log : RingBuffer<Event>(1024 * 1024)
34193419
34203420
@helper
34213421
fn transparent_dynptr_usage(event_data: *u8, data_len: u32) {
@@ -3509,7 +3509,7 @@ fn resource_safe_processing(input: *u8, len: u32) -> ProcessResult {
35093509
}
35103510
35113511
// Map value pointer lifetime tracking
3512-
map<u32, DataCache> cache_map : HashMap(1024)
3512+
var cache_map : HashMap<u32, DataCache>(1024)
35133513
35143514
@helper
35153515
fn map_lifetime_safety(key: u32) {
@@ -4140,9 +4140,9 @@ fn main(args: Args) -> i32 {
41404140
### 14.3 Performance Monitoring
41414141
```kernelscript
41424142
// Global maps for performance data
4143-
map<u32, CallInfo> active_calls : HashMap(1024)
4144-
map<u32, u64> read_stats : Array(1024)
4145-
map<u32, u64> write_stats : Array(1024)
4143+
var active_calls : HashMap<u32, CallInfo>(1024)
4144+
var read_stats : Array<u32, u64>(1024)
4145+
var write_stats : Array<u32, u64>(1024)
41464146
41474147
struct CallInfo {
41484148
start_time: u64,
@@ -4310,7 +4310,7 @@ global_declaration = config_declaration | map_declaration | type_declaration |
43104310
global_variable_declaration | bindings_declaration | import_declaration
43114311
43124312
(* Map declarations - global scope *)
4313-
map_declaration = [ "pin" ] [ "@flags" "(" flag_expression ")" ] "map" "<" key_type "," value_type ">" identifier ":" map_type "(" map_config ")"
4313+
map_declaration = [ "pin" ] [ "@flags" "(" flag_expression ")" ] "var" identifier ":" map_type "<" key_type "," value_type ">" "(" map_config ")"
43144314
43154315
map_type = "HashMap" | "Array" | "PerCpuHash" | "PerCpuArray" | "LruHash" |
43164316
"RingBuffer" | "PerfEvent" | "StackTrace" | "ProgArray"

examples/break_continue_unbound.ks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ enum xdp_action {
2020
// Example demonstrating break and continue in truly unbound loops
2121
// This should force bpf_loop() usage
2222

23-
map<u32, u32> counter_map : HashMap(10)
23+
var counter_map : HashMap<u32, u32>(10)
2424

2525
@xdp fn packet_filter(ctx: *xdp_md) -> xdp_action {
2626
var end_value = 1000 // Large value to make it unbound

examples/dynptr.ks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct DataBuffer {
2626
size: u32
2727
}
2828

29-
map<u32, DataBuffer> buffer_map : HashMap(1024)
29+
var buffer_map : HashMap<u32, DataBuffer>(1024)
3030

3131
@helper
3232
fn process_map_data(buffer_ptr: *DataBuffer) -> u32 {

examples/error_handling_demo.ks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ enum xdp_action {
1818
}
1919

2020
// Minimal error handling demo
21-
map<u32, u64> counters : HashMap(1024)
21+
var counters : HashMap<u32, u64>(1024)
2222

2323
@xdp fn error_demo(ctx: *xdp_md) -> xdp_action {
2424
var key = 42

examples/map_operations_demo.ks

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,19 @@ struct PerCpuData {
7373
// Global maps shared across multiple programs with the new simplified syntax
7474

7575
// Global counter with automatic path: /sys/fs/bpf/map_operations_demo/maps/global_counter
76-
pin map<u32, u64> global_counter : HashMap(10000)
76+
pin var global_counter : HashMap<u32, u64>(10000)
7777

7878
// Statistics map with read-only flags
79-
@flags(rdonly) pin map<u32, Statistics> shared_stats : HashMap(1000)
79+
@flags(rdonly) pin var shared_stats : HashMap<u32, Statistics>(1000)
8080

8181
// Per-CPU data with automatic pinning path: /sys/fs/bpf/map_operations_demo/maps/percpu_data
82-
pin map<u32, PerCpuData> percpu_data : PercpuHash(256)
82+
pin var percpu_data : PercpuHash<u32, PerCpuData>(256)
8383

8484
// Event stream ring buffer with no preallocation flag
85-
@flags(no_prealloc) pin map<u32, u32> event_stream : RingBuffer(65536)
85+
@flags(no_prealloc) pin var event_stream : RingBuffer<u32, u32>(65536)
8686

8787
// Sequential data array - not pinned (local to program)
88-
map<u32, ArrayElement> sequential_data : Array(1024)
88+
var sequential_data : Array<u32, ArrayElement>(1024)
8989

9090
struct Event {
9191
timestamp: u64,

examples/maps_demo.ks

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@ struct PacketStats {
4444
// Global maps with different configurations
4545

4646
// 1. Simple array map for per-CPU counters (pinned to filesystem)
47-
pin map<u32, Counter> cpu_counters : Array(256)
47+
pin var cpu_counters : Array<u32, Counter>(256)
4848

4949
// 2. Hash map for IP address tracking (pinned to filesystem)
50-
pin map<IpAddress, PacketStats> ip_stats : HashMap(10000)
50+
pin var ip_stats : HashMap<IpAddress, PacketStats>(10000)
5151

5252
// 3. LRU hash map for recent connections (local to program)
53-
map<IpAddress, u64> recent_connections : LruHash(1000)
53+
var recent_connections : LruHash<IpAddress, u64>(1000)
5454

5555
// 4. Ring buffer for event logging (pinned to filesystem)
56-
pin map<u32, u8> event_log : RingBuffer(65536)
56+
pin var event_log : RingBuffer<u32, u8>(65536)
5757

5858
// 5. Local state map (not pinned)
59-
map<u32, u32> local_state : HashMap(100)
59+
var local_state : HashMap<u32, u32>(100)
6060

6161
// 6. Per-CPU bandwidth tracking (pinned to filesystem)
62-
pin map<u32, u64> bandwidth_usage : PercpuArray(256)
62+
pin var bandwidth_usage : PercpuArray<u32, u64>(256)
6363

6464
@helper
6565
fn get_cpu_id() -> u32 {

examples/multi_programs.ks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ enum tc_action {
4040
TC_ACT_REDIRECT = 7,
4141
}
4242

43-
pin map<u32, u32> shared_counter : HashMap(1024)
43+
pin var shared_counter : HashMap<u32, u32>(1024)
4444

4545
// First eBPF program - packet counter
4646
@xdp fn packet_counter(ctx: *xdp_md) -> xdp_action {

examples/object_allocation.ks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct ConnStats {
2828
}
2929

3030
// Map to store connection statistics
31-
map<u32, *ConnStats> conn_tracker : HashMap(1024)
31+
var conn_tracker : HashMap<u32, *ConnStats>(1024)
3232

3333
@xdp fn packet_inspector(ctx: *xdp_md) -> xdp_action {
3434
// Simple source IP extraction (in real code, would parse ethernet/IP headers)

examples/rate_limiter.ks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ enum xdp_action {
1717
XDP_TX = 4,
1818
}
1919

20-
map<u32,u64>packet_counts : HashMap(1024)
20+
var packet_counts : HashMap<u32, u64>(1024)
2121

2222
config network {
2323
limit : u32,

0 commit comments

Comments
 (0)