Skip to content

feat(wasm): byte-level load/store IR + env_at/arg_at (ADR-015 S5)#339

Merged
hyperpolymath merged 2 commits into
mainfrom
claude/gracious-euler-uUVvX
May 24, 2026
Merged

feat(wasm): byte-level load/store IR + env_at/arg_at (ADR-015 S5)#339
hyperpolymath merged 2 commits into
mainfrom
claude/gracious-euler-uUVvX

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Unblocks INT-03 S5 (#180) by extending the wasm IR with the full WebAssembly 1.0 §5.4.6 byte-level load/store family (opcodes 0x2C..0x35, 0x3A..0x3E) and shipping the env_at(i) / arg_at(i) string accessors that were waiting on them.

  • IR + encoder (lib/wasm.ml + lib/wasm_encode.ml) — 14 new instr constructors (I32Load8{S,U}, I32Load16{S,U}, I64Load8{S,U}, I64Load16{S,U}, I64Load32{S,U}, I32Store8, I32Store16, I64Store{8,16,32}). Encoder pattern mirrors the existing full-width family one-for-one.
  • env_at / arg_at lowering (lib/typecheck.ml + lib/codegen.ml + lib/wasi_runtime.ml) — bind Int -> String / { Time }; lower via on-demand wasi_snapshot_preview1.{environ,args}_get imports paired with the existing *_sizes_get import. The codegen helper emits a 7-phase sequence: sizes_get → alloc ptrvec+bytebuf → *_get → resolve ptrvec[n] → null-terminator scan (I32Load8U) → alloc length-prefixed AS string → byte-copy (I32Load8U / I32Store8).
  • Import-table dedup (lib/codegen.ml) — env_count and env_at both require environ_sizes_get (ditto arg_count/arg_at). The optional_wasi table now lists every (builtin, wasi_import) pair and the assembly pass dedupes by WASI import name (first occurrence wins), preserving the canonical-order indexing the existing combo regression hardened.
  • Docs updated in docs/ECOSYSTEM.adoc and docs/TECH-DEBT.adoc; stale "tracked follow-up" comments in codegen/typecheck/wasi_runtime cleared.

Test plan

  • CI dune build + dune runtest (the only build environment available — see note below)
  • ./tools/run_codegen_wasm_tests.sh picks up the three new fixtures automatically:
    • tests/codegen/env_at.affine + test_env_at.mjs — smoke for string_length(env_at(0)); verifies environ_sizes_get + environ_get both fire and the byte-scan terminates at the right offset.
    • tests/codegen/arg_at.affine + test_arg_at.mjs — same shape over args_get, indexed at 1 to exercise the n*4 ptrvec offset (not just index = 0 short-circuit).
    • tests/codegen/env_count_and_at.affine + test_env_count_and_at.mjs — dedup regression: instantiation fails fast if environ_sizes_get is double-imported.

Caveat — local verification

The session container's network policy blocks opam.ocaml.org (host_not_allowed), so opam install . --deps-only fails and dune build cannot run locally. The five modified .ml files were syntax-checked with ocamlc -stop-after parsing (all OK) and the code mirrors existing patterns exactly, but the type-checker hasn't been run end-to-end against this branch. CI is the first real validation — autofix-on-failure is wired up to follow.

https://claude.ai/code/session_01FoWm87AnVtLS5euDEAGu2A


Generated by Claude Code

Unblock INT-03 S5 (#180) by extending the wasm IR with the full
WebAssembly 1.0 §5.4.6 byte-level load/store family (opcodes
0x2C..0x35, 0x3A..0x3E) and shipping the env_at(i)/arg_at(i)
string accessors that were waiting on them.

IR + encoder (lib/wasm.ml + lib/wasm_encode.ml):
  14 new instr constructors — I32Load8{S,U}, I32Load16{S,U},
  I64Load8{S,U}, I64Load16{S,U}, I64Load32{S,U}, I32Store8,
  I32Store16, I64Store{8,16,32}. Encoder pattern mirrors the
  existing full-width family one-for-one.

env_at / arg_at lowering (lib/typecheck.ml + lib/codegen.ml +
lib/wasi_runtime.ml):
  Bind Int -> String / { Time }; lower via on-demand
  `wasi_snapshot_preview1.{environ,args}_get` imports paired with
  the existing `_sizes_get` import. Emit a 7-phase sequence:
  sizes_get -> alloc ptrvec+bytebuf -> _get -> resolve src ptr
  via ptrvec[n] -> null-terminator scan (I32Load8U) -> alloc
  length-prefixed AS string -> byte-copy (I32Load8U/I32Store8).
  Codegen helper takes 11 pre-allocated locals; each call site
  scopes its own to keep slot reuse clean.

Import-table dedup (lib/codegen.ml):
  `env_count` and `env_at` both require `environ_sizes_get`
  (ditto arg_count/arg_at). The optional_wasi table now lists
  every (builtin, wasi_import) pair and the assembly pass dedupes
  by wasi import name, keeping first occurrence — preserves the
  canonical-order indexing the existing combo-regression hardened.

Tests (tests/codegen/{env_at,arg_at,env_count_and_at}.{affine,mjs}):
  Smoke for env_at(0) length, arg_at(1) length (exercises the
  n*4 ptrvec offset, not just index 0), and a dedup regression
  that drives a unit using BOTH env_count and env_at through one
  shared environ_sizes_get import.

Closes the "byte-level wasm IR" blocker called out in
docs/ECOSYSTEM.adoc, docs/TECH-DEBT.adoc, and the codegen/
typecheck/wasi_runtime comments (all updated).
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 143 issues detected

Severity Count
🔴 Critical 13
🟠 High 69
🟡 Medium 61

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stray AI.a2ml in root -- use 0-AI-MANIFEST.a2ml only",
    "type": "banned",
    "file": "AI.a2ml",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Superseded by 0-AI-MANIFEST.a2ml",
    "type": "banned",
    "file": "AI.djot",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action actions/checkout@v6 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action denoland/setup-deno@v2 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/example/smoke_driver.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/cli.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 58f08b9 into main May 24, 2026
10 of 15 checks passed
@hyperpolymath hyperpolymath deleted the claude/gracious-euler-uUVvX branch May 24, 2026 04:49
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 143 issues detected

Severity Count
🔴 Critical 13
🟠 High 69
🟡 Medium 61

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stray AI.a2ml in root -- use 0-AI-MANIFEST.a2ml only",
    "type": "banned",
    "file": "AI.a2ml",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Superseded by 0-AI-MANIFEST.a2ml",
    "type": "banned",
    "file": "AI.djot",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action actions/checkout@v6 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action denoland/setup-deno@v2 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/example/smoke_driver.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/cli.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants