Skip to content

Commit 56001e1

Browse files
committed
feat: WASM
1 parent 2372e95 commit 56001e1

File tree

4 files changed

+1498
-0
lines changed

4 files changed

+1498
-0
lines changed

.github/workflows/wasm-ci.yml

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
name: JSON-C WASM CI
2+
3+
on:
4+
push:
5+
branches: [wasm]
6+
pull_request:
7+
branches: [wasm]
8+
release:
9+
types: [created]
10+
11+
env:
12+
EMSCRIPTEN_VERSION: '4.0.13'
13+
NODE_VERSION: '22'
14+
15+
jobs:
16+
build:
17+
name: Build & Test JSON-C WASM
18+
runs-on: ubuntu-latest
19+
strategy:
20+
matrix:
21+
config: [Release, Debug]
22+
simd: [ON, OFF]
23+
fail-fast: false
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
with:
29+
submodules: recursive
30+
31+
- name: Setup Node.js
32+
uses: actions/setup-node@v4
33+
with:
34+
node-version: ${{ env.NODE_VERSION }}
35+
36+
- name: Setup Emscripten SDK
37+
uses: mymindstorm/setup-emsdk@v14
38+
with:
39+
version: ${{ env.EMSCRIPTEN_VERSION }}
40+
actions-cache-folder: 'emsdk-cache'
41+
42+
- name: Install build dependencies
43+
run: |
44+
sudo apt-get update
45+
sudo apt-get install -y cmake ninja-build
46+
47+
- name: Install binaryen for optimization
48+
run: |
49+
sudo apt-get install -y binaryen
50+
51+
- name: Build WASM module
52+
run: |
53+
chmod +x build-wasm.sh
54+
./build-wasm.sh ${{ matrix.config }} ${{ matrix.simd }}
55+
56+
- name: Validate build outputs
57+
run: |
58+
echo "Checking build artifacts..."
59+
ls -la dist/
60+
61+
# Check required files exist
62+
files=("json-c.js" "json-c.wasm" "json-c.d.ts" "package.json" "README.md")
63+
for file in "${files[@]}"; do
64+
if [ -f "dist/$file" ]; then
65+
echo "✓ $file exists ($(du -h dist/$file | cut -f1))"
66+
else
67+
echo "✗ $file missing"
68+
exit 1
69+
fi
70+
done
71+
72+
# Check SIMD build if enabled
73+
if [ "${{ matrix.simd }}" = "ON" ] && [ -f "dist/json-c-simd.js" ]; then
74+
echo "✓ SIMD build found ($(du -h dist/json-c-simd.js | cut -f1))"
75+
fi
76+
77+
- name: Install Node.js test dependencies
78+
run: |
79+
echo '{"type": "module"}' > package.json
80+
81+
- name: Run integration tests
82+
run: |
83+
echo "Running WASM integration tests..."
84+
node tests/wasm_integration_test.js
85+
86+
- name: Upload build artifacts
87+
uses: actions/upload-artifact@v4
88+
with:
89+
name: json-c-wasm-${{ matrix.config }}-simd-${{ matrix.simd }}
90+
path: dist/
91+
retention-days: 30
92+
93+
performance:
94+
name: Performance Benchmarks
95+
needs: build
96+
runs-on: ubuntu-latest
97+
if: github.ref == 'refs/heads/wasm'
98+
99+
steps:
100+
- name: Checkout repository
101+
uses: actions/checkout@v4
102+
103+
- name: Setup Node.js
104+
uses: actions/setup-node@v4
105+
with:
106+
node-version: ${{ env.NODE_VERSION }}
107+
108+
- name: Download build artifacts
109+
uses: actions/download-artifact@v4
110+
with:
111+
name: json-c-wasm-Release-simd-ON
112+
path: dist/
113+
114+
- name: Run performance benchmarks
115+
run: |
116+
echo '{"type": "module"}' > package.json
117+
echo "## 📊 JSON-C.wasm Performance Benchmarks" >> $GITHUB_STEP_SUMMARY
118+
echo "" >> $GITHUB_STEP_SUMMARY
119+
120+
# Create benchmark script
121+
cat > benchmark.js << 'EOF'
122+
import { promises as fs } from 'fs';
123+
124+
const testCases = {
125+
simple: '{"name": "test", "value": 42}',
126+
nested: '{"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}',
127+
large: JSON.stringify({data: Array(100).fill({id: 1, name: "test"})})
128+
};
129+
130+
async function runBenchmarks() {
131+
try {
132+
const { default: JsonCModule } = await import('./dist/json-c.js');
133+
const module = await JsonCModule();
134+
const benchmark = module.cwrap('json_c_benchmark_parsing', 'number', ['string', 'number']);
135+
136+
console.log("| Test Case | Iterations | Duration | Throughput |");
137+
console.log("|-----------|------------|----------|------------|");
138+
139+
Object.entries(testCases).forEach(([name, json]) => {
140+
const iterations = name === 'large' ? 50 : 200;
141+
const duration = benchmark(json, iterations);
142+
const throughput = Math.round(iterations / (duration / 1000));
143+
console.log(`| ${name} | ${iterations} | ${duration.toFixed(2)}ms | ${throughput} ops/sec |`);
144+
});
145+
} catch (err) {
146+
console.log("Benchmark failed:", err.message);
147+
}
148+
}
149+
150+
runBenchmarks();
151+
EOF
152+
153+
node benchmark.js >> $GITHUB_STEP_SUMMARY
154+
155+
quality:
156+
name: Code Quality & Security
157+
runs-on: ubuntu-latest
158+
159+
steps:
160+
- name: Checkout repository
161+
uses: actions/checkout@v4
162+
163+
- name: Check for security issues
164+
run: |
165+
echo "Checking for security issues in C code..."
166+
if grep -r "gets\|strcpy\|sprintf\|password\|secret\|key" --exclude-dir=.git --exclude="*.md" --exclude="*.yml" --include="*.c" --include="*.h" .; then
167+
echo "⚠️ Potential security issues found"
168+
else
169+
echo "✓ No obvious security issues detected"
170+
fi
171+
172+
- name: Validate build configuration
173+
run: |
174+
echo "Checking CMake configuration..."
175+
if grep -q "ENABLE_THREADING=OFF" CMakeLists.txt; then
176+
echo "✓ Threading disabled for WASM compatibility"
177+
fi
178+
179+
release:
180+
name: Release Package
181+
needs: [build, performance, quality]
182+
runs-on: ubuntu-latest
183+
if: github.event_name == 'release'
184+
185+
steps:
186+
- name: Checkout repository
187+
uses: actions/checkout@v4
188+
189+
- name: Setup Emscripten SDK
190+
uses: mymindstorm/setup-emsdk@v14
191+
with:
192+
version: ${{ env.EMSCRIPTEN_VERSION }}
193+
194+
- name: Build release package
195+
run: |
196+
chmod +x build-wasm.sh
197+
./build-wasm.sh Release ON
198+
199+
- name: Create release archive
200+
run: |
201+
tar -czf json-c-wasm-${{ github.event.release.tag_name }}.tar.gz dist/ docs/ README.md
202+
203+
- name: Upload release assets
204+
uses: actions/upload-release-asset@v1
205+
env:
206+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
207+
with:
208+
upload_url: ${{ github.event.release.upload_url }}
209+
asset_path: json-c-wasm-${{ github.event.release.tag_name }}.tar.gz
210+
asset_name: json-c-wasm-${{ github.event.release.tag_name }}.tar.gz
211+
asset_content_type: application/gzip

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,31 @@
9494
# Benchmarking input and output
9595
/bench/data
9696
/bench/work
97+
98+
# WASM build artifacts
99+
dist/
100+
build-wasm*/
101+
*.wasm
102+
*.js.mem
103+
*.js.symbols
104+
*.js.temp
105+
*.wast
106+
*.wat
107+
108+
# Emscripten cache and tools
109+
emsdk/
110+
emsdk_env.sh
111+
.emscripten_cache/
112+
113+
# Node.js and NPM
114+
node_modules/
115+
package-lock.json
116+
yarn.lock
117+
npm-debug.log*
118+
119+
# Testing and CI artifacts
120+
test-results/
121+
benchmark-results/
122+
coverage/
123+
.nyc_output/
124+
build-logs/

0 commit comments

Comments
 (0)