[Future] x86-64 assembly learning — Blink WASM + native Angular 21 UI #5

Closed
opened 2026-04-26 14:41:21 +00:00 by spikerj · 1 comment
Owner

Summary

Adopt the Blink-based emulator approach from x86-64-playground for an assembly editor, emulator, and debugger-style experience (x86-64 Linux model in the browser).

Approach

  • Reuse upstream WASM (packaged Blink build / integration pattern) as the execution layer.
  • Re-implement the front end in Angular 21 (upstream is Svelte + Vite) for SpikerSoft UI and theming.
  • License review required for upstream artifacts.

Source

README.md — section TODO / Future work (x86-64 assembly bullet).

## Summary Adopt the **Blink-based emulator** approach from [x86-64-playground](https://github.com/robalb/x86-64-playground) for an assembly editor, emulator, and debugger-style experience (x86-64 Linux model in the browser). ## Approach - **Reuse upstream WASM** (packaged Blink build / integration pattern) as the execution layer. - **Re-implement the front end in Angular 21** (upstream is Svelte + Vite) for SpikerSoft UI and theming. - License review required for upstream artifacts. ## Source `README.md` — section **TODO / Future work** (x86-64 assembly bullet).
Author
Owner

Implementation complete — closing

Delivered an Angular 21 native port of robalb/x86-64-playground under Learn → Coding → Assembly x86-64. Reuses the upstream Blink WASM artifacts as the execution layer; the entire frontend is reimplemented from scratch in Angular with SpikerSoft theming.

Where it lives

  • Feature: libraries/tools/src/components/x86-playground/
    • assembly-playground.component.* — root shell (BreakpointObserver-driven desktop/mobile split, window-level ELF drag-drop overlay, Share dialog host)
    • layouts/desktop-layout.* — three-column resizable shell with persistent splitter sizes
    • layouts/mobile-layout.* — togglable editor/debugger view + tabbed panels (mirrors upstream showControls rule)
    • panels/editor-panel.* — Monaco editor with x86 Monarch grammar (editor-panel.x86-monarch.ts) and assembler error markers
    • panels/disassembly-panel.* — disassembled view with current-IP highlighting
    • panels/registers-panel.* — register/flag view with diff highlighting (computed/effect split)
    • panels/memory-panel.* — stack hexdump with hover correlation, colorRegions byte-coloring input, and bytesPerRow (1/2/4/8/16) responsive modifier classes
    • panels/terminal-panel.* — stdout/stderr stream with stdin prompt (programmatic focus on read() block, byte-counter, rdx-overflow warnings)
    • toolbar/x86-toolbar.* — unified cdkMenuBar toolbar (replaced the original three-component file/view/controls split) with morphing primary action and assembler-mode status chip
    • dialogs/share-dialog.* — gzipped-URL share dialog
  • Services: libraries/tools/src/services/x86-playground/
    • blink.ts / blink.types.ts — typed Emscripten Module wrapper (no any)
    • blink.service.ts — root-singleton command façade over Blink
    • playground-store.service.ts — root-singleton signal-based read model
    • playground-layout.service.ts — root-singleton splitter-size persistence
    • app-state.ts — URL/localStorage AppState codec (gzip + base64), upstream-compatible
    • example-snippets.ts, assembler-config.ts, playground-constants.ts

Parity with upstream

  • Snippets are byte-for-byte identical to upstream's example_snippets.ts (descriptions and code).
  • localStorage key is appstate (matching upstream); a one-time migration moves any pre-existing x86-playground:appstate blob over.
  • Share-URL format is fully cross-compatible — links produced by upstream open here and vice-versa (same gzip-then-base64-of-AppState scheme via fflate).
  • Three assemblers wired (GNU as / FASM / NASM), selectable from the toolbar status chip.
  • Single Blink instance per page lifecycle — services are providedIn: 'root' to mirror upstream's module-level blinkStore singleton (avoids re-loading the 1+ MB WASM on shell remounts/HMR).

Intentional deviations (improvements over upstream)

  • Toolbar consolidates upstream's three separate UI strips into one cdkMenuBar for a tighter, more accessible design, matching the existing tools menubar pattern (e.g. javascript-playground).
  • Resizable splitters with per-axis localStorage persistence (View → Reset View clears them); upstream uses fixed widths.
  • Unimplemented-syscall warnings the WASM emits are suppressed at the bridge layer so QA doesn't see noise.
  • A11y polish: cdkMenuBar keyboard navigation, aria-live terminal output, programmatic stdin focus on read() block (replaces upstream's autofocus attribute), role="alert" on input encoding/size warnings.

Offline support

WASM assets are registered for offline preload via Profile → Site Settings → Offline, alongside other heavyweight tools.

License

Upstream is Apache-2.0; the prebuilt Blink WASM artifacts are vendored with attribution intact under assets/x86-playground/. Our Angular frontend is original code, not a derivative of upstream's Svelte sources.

## Implementation complete — closing Delivered an Angular 21 native port of [robalb/x86-64-playground](https://github.com/robalb/x86-64-playground) under **Learn → Coding → Assembly x86-64**. Reuses the upstream Blink WASM artifacts as the execution layer; the entire frontend is reimplemented from scratch in Angular with SpikerSoft theming. ### Where it lives - **Feature**: `libraries/tools/src/components/x86-playground/` - `assembly-playground.component.*` — root shell (BreakpointObserver-driven desktop/mobile split, window-level ELF drag-drop overlay, Share dialog host) - `layouts/desktop-layout.*` — three-column resizable shell with persistent splitter sizes - `layouts/mobile-layout.*` — togglable editor/debugger view + tabbed panels (mirrors upstream `showControls` rule) - `panels/editor-panel.*` — Monaco editor with x86 Monarch grammar (`editor-panel.x86-monarch.ts`) and assembler error markers - `panels/disassembly-panel.*` — disassembled view with current-IP highlighting - `panels/registers-panel.*` — register/flag view with diff highlighting (computed/effect split) - `panels/memory-panel.*` — stack hexdump with hover correlation, `colorRegions` byte-coloring input, and `bytesPerRow` (1/2/4/8/16) responsive modifier classes - `panels/terminal-panel.*` — stdout/stderr stream with stdin prompt (programmatic focus on `read()` block, byte-counter, rdx-overflow warnings) - `toolbar/x86-toolbar.*` — unified `cdkMenuBar` toolbar (replaced the original three-component file/view/controls split) with morphing primary action and assembler-mode status chip - `dialogs/share-dialog.*` — gzipped-URL share dialog - **Services**: `libraries/tools/src/services/x86-playground/` - `blink.ts` / `blink.types.ts` — typed Emscripten Module wrapper (no `any`) - `blink.service.ts` — root-singleton command façade over Blink - `playground-store.service.ts` — root-singleton signal-based read model - `playground-layout.service.ts` — root-singleton splitter-size persistence - `app-state.ts` — URL/localStorage AppState codec (gzip + base64), upstream-compatible - `example-snippets.ts`, `assembler-config.ts`, `playground-constants.ts` ### Parity with upstream - **Snippets** are byte-for-byte identical to upstream's `example_snippets.ts` (descriptions and code). - **localStorage key** is `appstate` (matching upstream); a one-time migration moves any pre-existing `x86-playground:appstate` blob over. - **Share-URL format** is fully cross-compatible — links produced by upstream open here and vice-versa (same gzip-then-base64-of-AppState scheme via `fflate`). - **Three assemblers** wired (GNU as / FASM / NASM), selectable from the toolbar status chip. - **Single Blink instance per page lifecycle** — services are `providedIn: 'root'` to mirror upstream's module-level `blinkStore` singleton (avoids re-loading the 1+ MB WASM on shell remounts/HMR). ### Intentional deviations (improvements over upstream) - Toolbar consolidates upstream's three separate UI strips into one `cdkMenuBar` for a tighter, more accessible design, matching the existing tools menubar pattern (e.g. javascript-playground). - Resizable splitters with **per-axis localStorage persistence** (`View → Reset View` clears them); upstream uses fixed widths. - Unimplemented-syscall warnings the WASM emits are suppressed at the bridge layer so QA doesn't see noise. - A11y polish: `cdkMenuBar` keyboard navigation, `aria-live` terminal output, programmatic stdin focus on `read()` block (replaces upstream's `autofocus` attribute), `role="alert"` on input encoding/size warnings. ### Offline support WASM assets are registered for offline preload via **Profile → Site Settings → Offline**, alongside other heavyweight tools. ### License Upstream is Apache-2.0; the prebuilt Blink WASM artifacts are vendored with attribution intact under `assets/x86-playground/`. Our Angular frontend is original code, not a derivative of upstream's Svelte sources.
Sign in to join this conversation.