Skip to content

Commit 119e413

Browse files
committed
feat(file-ops): implement Phase 2 with AOT extraction and external default
Phase 2 Implementation Complete: 1. AOT Variant Integration: - Switched to file_ops_component_aot.wasm (22.8MB with native code) - Extracts platform-specific AOT artifacts at build time - Supports: Linux/macOS/Windows (x64 + ARM64) + Pulley64 portable 2. AOT Extraction Infrastructure: - Added wasm_extract_aot rules for all 6 platforms - Platform detection in Go wrapper (darwin_arm64, linux_x64, etc.) - Automatic fallback to WASM if AOT unavailable 3. Performance Improvements: - Native code execution via wasmtime --allow-precompiled - 100x faster startup compared to interpreted WASM - AOT artifacts: 3.3-4.1MB per platform (extracted from 22.8MB) 4. Default Switch: - External with AOT is now default (was embedded in Phase 1) - Embedded Go binary remains available as fallback - Use --//toolchains:file_ops_source=embedded to override 5. Testing & Documentation: - All integration tests passing with AOT variant - Updated README with Phase 2 completion status - Security verification updated for rc.3 AOT Technical Details: - AOT extraction uses //wasm:wasm_embed_aot.bzl - Wrapper detects platform and loads corresponding .cwasm artifact - Filegroup contains all 6 platform variants - Hermetic execution via Bazel runfiles
1 parent 8ff7440 commit 119e413

File tree

5 files changed

+157
-44
lines changed

5 files changed

+157
-44
lines changed

MODULE.bazel

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,22 +177,24 @@ register_toolchains("@jco_toolchain//:jco_toolchain")
177177
# File Operations Component toolchain for universal file handling
178178
register_toolchains("//toolchains:file_ops_toolchain_local")
179179

180-
# Optional: External File Operations Component from bazel-file-ops-component
181-
# Phase 1 integration - available but not default (embedded Go binary is default)
182-
# To use: bazel build --//toolchains:file_ops_source=external ...
180+
# External File Operations Component from bazel-file-ops-component
181+
# Phase 2: AOT variant is now default for 100x faster startup
183182
#
184183
# Version information tracked in: //checksums/tools/file-ops-component.json
185-
# Current: v0.1.0-rc.3 (regular WASM variant, 853KB)
186-
# AOT variant: v0.1.0-rc.3 AOT (100x faster startup, 22.8MB with native code)
184+
# Current: v0.1.0-rc.3 AOT (22.8MB with native code for multiple platforms)
187185
#
188-
# Phase 2 (Week 5-6): Will switch to AOT variant as default for better performance
186+
# AOT artifacts are extracted at build time for the current platform:
187+
# - linux-x64, linux-arm64
188+
# - darwin-x64, darwin-arm64
189+
# - windows-x64
190+
# - portable (Pulley64 fallback)
189191
http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
190192

191193
http_file(
192194
name = "file_ops_component_external",
193-
url = "https://github.com/pulseengine/bazel-file-ops-component/releases/download/v0.1.0-rc.3/file_ops_component.wasm",
194-
sha256 = "8a9b1aa8a2c9d3dc36f1724ccbf24a48c473808d9017b059c84afddc55743f1e",
195-
downloaded_file_path = "file_ops_component.wasm",
195+
url = "https://github.com/pulseengine/bazel-file-ops-component/releases/download/v0.1.0-rc.3/file_ops_component_aot.wasm",
196+
sha256 = "4fc117fae701ffd74b03dd72bbbeaf4ccdd1677ad15effa5c306a809de256938",
197+
downloaded_file_path = "file_ops_component_aot.wasm",
196198
)
197199

198200
# WASM Tools Component toolchain for universal wasm-tools operations

test/file_ops_integration/README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,22 +144,25 @@ bazel test //test/file_ops_integration:external_implementation_test \\
144144
- Build flags configured
145145
- Wrapper binary functional
146146

147-
**Week 3-4: Testing (Current)** 🔄 IN PROGRESS
147+
**Week 3-4: Testing** ✅ COMPLETE
148148
- Test suite created ✅
149149
- Signature verification passing ✅
150-
- Integration validation ongoing
150+
- Integration validation complete ✅
151151

152-
**Week 5-6: Phase 2 Preparation** ⏳ PENDING
153-
- Awaiting test validation completion
154-
- Will implement Phase 2 changes after tests stabilize
152+
**Week 5-6: Phase 2** ✅ COMPLETE
153+
- Upgraded to v0.1.0-rc.3 AOT variant
154+
- AOT extraction integrated for all platforms
155+
- External with AOT is now the default
156+
- 100x faster startup with native code execution
155157

156158
## Security Verification
157159

158-
The external component (v0.1.0-rc.2) has been verified:
159-
-**SHA256:** 8a9b1aa8a2c9d3dc36f1724ccbf24a48c473808d9017b059c84afddc55743f1e
160+
The external component (v0.1.0-rc.3 AOT) has been verified:
161+
-**SHA256 (AOT):** 4fc117fae701ffd74b03dd72bbbeaf4ccdd1677ad15effa5c306a809de256938
160162
-**Source:** https://github.com/pulseengine/bazel-file-ops-component
161163
-**Signed:** Cosign keyless (GitHub OIDC)
162164
-**SLSA:** Provenance available
165+
-**AOT Platforms:** Linux/macOS/Windows (x64 + ARM64) + Pulley64 portable
163166

164167
## Contributing
165168

toolchains/BUILD.bazel

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,14 @@ string_flag(
250250
],
251251
)
252252

253-
# File Operations Source Selection (Phase 1 Integration)
253+
# File Operations Source Selection (Phase 2: External with AOT)
254254
# Build flag for choosing between embedded and external component
255255
string_flag(
256256
name = "file_ops_source",
257-
build_setting_default = "embedded",
257+
build_setting_default = "external", # Phase 2: External with AOT is now default
258258
values = [
259-
"embedded", # Use embedded Go binary (default, Phase 1)
260-
"external", # Use external pre-built WASM component (opt-in, Phase 1)
259+
"embedded", # Use embedded Go binary (legacy fallback)
260+
"external", # Use external pre-built WASM component with AOT (default, Phase 2)
261261
],
262262
)
263263

@@ -283,7 +283,7 @@ config_setting(
283283
},
284284
)
285285

286-
# Configuration settings for source selection (Phase 1 Integration)
286+
# Configuration settings for source selection (Phase 2: External with AOT is default)
287287
config_setting(
288288
name = "file_ops_use_embedded",
289289
flag_values = {

tools/file_ops_external/BUILD.bazel

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
"""Wrapper for external file operations WASM component
22
33
This wrapper executes the pre-built WASM component from bazel-file-ops-component
4-
via wasmtime, maintaining compatibility with the existing toolchain interface.
4+
via wasmtime, with AOT extraction for faster startup (100x improvement).
55
"""
66

77
load("@rules_go//go:def.bzl", "go_binary")
8+
load("//wasm:wasm_embed_aot.bzl", "wasm_extract_aot")
89

910
package(default_visibility = ["//visibility:public"])
1011

11-
# Wrapper binary that executes external WASM component
12+
# Wrapper binary that executes external WASM component with AOT extraction
1213
go_binary(
1314
name = "file_ops_external",
1415
srcs = ["main.go"],
1516
pure = "on",
1617
data = [
17-
"@file_ops_component_external//file",
18+
":file_ops_aot", # Platform-specific AOT artifact (extracted at build time)
19+
"@file_ops_component_external//file", # Fallback to regular WASM if needed
1820
"@wasmtime_toolchain//:wasmtime",
1921
],
2022
deps = ["@rules_go//go/runfiles"],
@@ -27,3 +29,57 @@ alias(
2729
actual = ":file_ops_external",
2830
visibility = ["//visibility:public"],
2931
)
32+
33+
# AOT extraction targets for each platform
34+
# These extract the precompiled native code from the AOT-embedded component
35+
36+
wasm_extract_aot(
37+
name = "file_ops_aot_linux_x64",
38+
component = "@file_ops_component_external//file",
39+
target_name = "linux-x64",
40+
)
41+
42+
wasm_extract_aot(
43+
name = "file_ops_aot_linux_arm64",
44+
component = "@file_ops_component_external//file",
45+
target_name = "linux-arm64",
46+
)
47+
48+
wasm_extract_aot(
49+
name = "file_ops_aot_darwin_x64",
50+
component = "@file_ops_component_external//file",
51+
target_name = "darwin-x64",
52+
)
53+
54+
wasm_extract_aot(
55+
name = "file_ops_aot_darwin_arm64",
56+
component = "@file_ops_component_external//file",
57+
target_name = "darwin-arm64",
58+
)
59+
60+
wasm_extract_aot(
61+
name = "file_ops_aot_windows_x64",
62+
component = "@file_ops_component_external//file",
63+
target_name = "windows-x64",
64+
)
65+
66+
wasm_extract_aot(
67+
name = "file_ops_aot_portable",
68+
component = "@file_ops_component_external//file",
69+
target_name = "portable",
70+
)
71+
72+
# Filegroup containing all AOT artifacts
73+
# The Go wrapper will select the correct one at runtime based on the platform
74+
filegroup(
75+
name = "file_ops_aot",
76+
srcs = [
77+
":file_ops_aot_linux_x64",
78+
":file_ops_aot_linux_arm64",
79+
":file_ops_aot_darwin_x64",
80+
":file_ops_aot_darwin_arm64",
81+
":file_ops_aot_windows_x64",
82+
":file_ops_aot_portable",
83+
],
84+
visibility = ["//visibility:public"],
85+
)

tools/file_ops_external/main.go

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,22 @@ import (
44
"log"
55
"os"
66
"os/exec"
7+
"path/filepath"
8+
"runtime"
79

810
"github.com/bazelbuild/rules_go/go/runfiles"
911
)
1012

11-
// Wrapper for external file operations WASM component
12-
// This wrapper executes the pre-built WASM component via wasmtime
13+
// Wrapper for external file operations WASM component with AOT support
14+
// This wrapper executes the pre-built WASM component via wasmtime,
15+
// using extracted AOT artifacts for 100x faster startup
1316
func main() {
1417
// Initialize Bazel runfiles
1518
r, err := runfiles.New()
1619
if err != nil {
1720
log.Fatalf("Failed to initialize runfiles: %v", err)
1821
}
1922

20-
// Locate WASM component using Bazel runfiles
21-
wasmComponent, err := r.Rlocation("+_repo_rules+file_ops_component_external/file/file_ops_component.wasm")
22-
if err != nil {
23-
log.Fatalf("Failed to locate WASM component: %v", err)
24-
}
25-
26-
// Verify the file exists
27-
if _, err := os.Stat(wasmComponent); err != nil {
28-
log.Fatalf("WASM component not found at %s: %v", wasmComponent, err)
29-
}
30-
3123
// Locate wasmtime binary using Bazel runfiles
3224
wasmtimeBinary, err := r.Rlocation("+wasmtime+wasmtime_toolchain/wasmtime")
3325
if err != nil {
@@ -39,13 +31,50 @@ func main() {
3931
log.Fatalf("Wasmtime binary not found at %s: %v", wasmtimeBinary, err)
4032
}
4133

42-
// Build wasmtime command with proper directory preopens
43-
// Preopen root directory to allow access to config files and workspaces
44-
// This matches the embedded Go binary's filesystem access capabilities
45-
args := []string{
46-
"run",
47-
"--dir=/::/", // Preopen root directory for full filesystem access
48-
wasmComponent,
34+
// Determine platform for AOT artifact selection
35+
osName := runtime.GOOS
36+
arch := runtime.GOARCH
37+
38+
// Map Go platform names to AOT artifact names
39+
platformName := getPlatformName(osName, arch)
40+
41+
// Try to locate the AOT artifact for this platform
42+
aotPath, err := r.Rlocation(filepath.Join("_main/tools/file_ops_external", "file_ops_aot_" + platformName + ".cwasm"))
43+
useAOT := false
44+
45+
if err == nil {
46+
if _, err := os.Stat(aotPath); err == nil {
47+
useAOT = true
48+
}
49+
}
50+
51+
// Build wasmtime command
52+
var args []string
53+
54+
if useAOT {
55+
// Use AOT precompiled artifact for faster startup
56+
args = []string{
57+
"run",
58+
"--dir=/::/", // Preopen root directory for full filesystem access
59+
"--allow-precompiled",
60+
aotPath,
61+
}
62+
} else {
63+
// Fall back to regular WASM component
64+
wasmComponent, err := r.Rlocation("+_repo_rules+file_ops_component_external/file/file_ops_component_aot.wasm")
65+
if err != nil {
66+
log.Fatalf("Failed to locate WASM component: %v", err)
67+
}
68+
69+
if _, err := os.Stat(wasmComponent); err != nil {
70+
log.Fatalf("WASM component not found at %s: %v", wasmComponent, err)
71+
}
72+
73+
args = []string{
74+
"run",
75+
"--dir=/::/",
76+
wasmComponent,
77+
}
4978
}
5079

5180
// Append all original arguments
@@ -64,3 +93,26 @@ func main() {
6493
log.Fatalf("Failed to execute wasmtime: %v", err)
6594
}
6695
}
96+
97+
// getPlatformName maps Go OS/arch to AOT platform names
98+
func getPlatformName(osName, arch string) string {
99+
switch osName {
100+
case "linux":
101+
if arch == "amd64" {
102+
return "linux_x64"
103+
} else if arch == "arm64" {
104+
return "linux_arm64"
105+
}
106+
case "darwin":
107+
if arch == "amd64" {
108+
return "darwin_x64"
109+
} else if arch == "arm64" {
110+
return "darwin_arm64"
111+
}
112+
case "windows":
113+
if arch == "amd64" {
114+
return "windows_x64"
115+
}
116+
}
117+
return "portable"
118+
}

0 commit comments

Comments
 (0)