<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>obfuscatism</title>
    <description>柏原秀蔵です。東京でソフトウェアエンジニアやってます。 最近は難読化とかやっていません。 本ブログは個人の意見・見解であり、所属組織を代表したものではありません。
</description>
    <link>https://blog.obfuscatism.net/</link>
    <atom:link href="https://blog.obfuscatism.net/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 31 Jul 2026 23:09:38 +0900</pubDate>
    <lastBuildDate>Fri, 31 Jul 2026 23:09:38 +0900</lastBuildDate>
    <generator>Jekyll v3.9.3</generator>
    
      <item>
        <title>2026年、Amazon Kindle Scribe を買う</title>
        <description>&lt;p&gt;先日Amazon Kindle Scribe (2026)を購入した。
Kindle Oasis を長く使っていたので、それ以来のKindle端末の購入である。&lt;/p&gt;

&lt;h2 id=&quot;kindle-scribe-の特徴&quot;&gt;Kindle Scribe の特徴&lt;/h2&gt;

&lt;p&gt;Kindle Scribeの主なスペック&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;11 インチディスプレイ&lt;/li&gt;
  &lt;li&gt;フロントライト無し（今回は安いほうを選択し、調光ライトも無いモデル）&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;プレミアムペン付き&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/dp/B0FBSC6CPR&quot;&gt;New Amazon Kindle Scribe フロントライト非搭載モデル | 11インチディスプレイ、16GBストレージ、ノート機能搭載、プレミアムペン付き、グラファイト&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/dp/B0H5V3B1G1/&quot;&gt;MoKo Kindle Scribe 11 2026 ケース 第3世代 11インチ Scribe Colorsoft マグネット吸着式 Black&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;カバーは公式のものではなく、別メーカーのものを同時購入した。
重量は少々あるが、マグネットでKindle本体とよくくっついているので安定度は高い。&lt;/p&gt;

&lt;h2 id=&quot;oasis比体感スピード&quot;&gt;Oasis比体感スピード&lt;/h2&gt;
&lt;p&gt;そして、ページめくりが速い。
Kindle Oasisと比べて2倍くらい速くなったような気がする。
2024年モデルから速かったらしい。&lt;/p&gt;

&lt;p&gt;ニュース記事を読んでいると、プロセッサ（SoC）も強化されたそうだ。
ページめくりが速いということは、購入済み書籍のブラウジングや、ダウンロード済み書籍の検索なども素早く行えるようになっているということ。
速度が速いだけではあるが、書籍を読む上で速いと嬉しい周辺のUIがかなり快適になっている。&lt;/p&gt;

&lt;h2 id=&quot;プレミアムペンでの書き心地&quot;&gt;プレミアムペンでの書き心地&lt;/h2&gt;

&lt;p&gt;これもまた体感的な感想にはなるが、ペンでの書き心地がとても良い。
ディスプレイとペンの間に適度なざらざら感がある。&lt;/p&gt;

&lt;p&gt;ブログネタや思考の整理を、病院の通院中に読書ついでに実行してみたりしている。&lt;/p&gt;

&lt;h2 id=&quot;最後に&quot;&gt;最後に&lt;/h2&gt;

&lt;p&gt;ただし、端末がデカいといえばデカい。ほぼiPadくらいある。
大きい分、文字サイズも大きくして書籍を読みやすい状態にするのが正しい使い方であろう。。。&lt;/p&gt;
</description>
        <pubDate>Fri, 31 Jul 2026 22:45:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2026/07/31/new-amazon-kindle-scribe.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2026/07/31/new-amazon-kindle-scribe.html</guid>
        
        
      </item>
    
      <item>
        <title>x86_64→ARM64 バイナリトランスレータの設計と実装</title>
        <description>&lt;p&gt;Rosetta 2を参考にバイナリトランスレータを作成したので、学んだことをブログにまとめる。趣味の文書のため網羅性・正確性は保証しないが、アーキテクチャの雰囲気は伝わるはず&lt;/p&gt;

&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;Rosetta 2 (&lt;a href=&quot;https://ja.wikipedia.org/wiki/Rosetta&quot;&gt;Wikipedia&lt;/a&gt;) は、macOS上で動作する互換レイヤのソフトウェアである（&lt;a href=&quot;https://en.wikipedia.org/wiki/Rosetta_(software)&quot;&gt;Wikipedia Rosetta (software) (English)&lt;/a&gt;）。
Apple Silicon搭載Macであれば、x86_64（Intel Mac）向け実行ファイルをそのまま動かせる仕組みである
技術的にはバイナリトランスレーションとAOT(Ahead of Time)をベースとしている。
実行時の動的変換、あるいはAOTによる事前変換により、異なるCPUアーキテクチャのプログラムを短い起動・実行時間で動かす工夫がされている。&lt;/p&gt;

&lt;p&gt;Rosetta 2について調べ、macOS向けに実装したのがこちら。
&lt;a href=&quot;https://github.com/suma/rustmute&quot;&gt;https://github.com/suma/rustmute&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;モチベーション&quot;&gt;モチベーション&lt;/h2&gt;

&lt;p&gt;Wikipediaやニュースによると、将来Rosetta 2はmacOSから削除されるらしい。
また、バイナリトランスレーションは漢のロマン、ということで実際にClaude Codeで実際に作ってどんなものか体験してみたい。&lt;/p&gt;

&lt;p&gt;趣旨は次の点になる&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;macOS上で実際に動くバイナリトランスレーションの実装を作る（手でコードを書かず、コーディングエージェントClaude Codeの使用可）&lt;/li&gt;
  &lt;li&gt;x86_64向けのコードのCLIである程度は動くようにする&lt;/li&gt;
  &lt;li&gt;作ること、理解することが目的なので、各種属性（製品としてのクオリティ、速さ、安全性など）は重視しない。が、最後に気を付ける点をあげても面白いかもしれない&lt;/li&gt;
  &lt;li&gt;本ブログ執筆にあたって、LLM及び生成物（markdown, source code）は利用してもよい&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;このブログエントリで言及しないこと、書かないこと：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Claude CodeやLLMのプロンプト、ハウツー&lt;/li&gt;
  &lt;li&gt;バイナリトランスレータの作り方、実装の仕方など（だけど仕組みの解説はする！）&lt;/li&gt;
  &lt;li&gt;ソースコードのスニペットなどは貼り付けない&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;このブログエントリはLLMの生成物が一部入るかもだが、基本的には人間によって執筆されている。&lt;/p&gt;

&lt;h2 id=&quot;設計の開始&quot;&gt;設計の開始&lt;/h2&gt;

&lt;p&gt;Claude Codeで愚直にアーキテクチャを聞いたところ、Rosetta 2 クローンの設計はすぐ出てきた。
書籍『System Design Interview』にありそうな内容で、実装するだけなら丁度良い難易度である。&lt;/p&gt;

&lt;h3 id=&quot;全体&quot;&gt;全体&lt;/h3&gt;

&lt;p&gt;x86-64バイナリとそれが利用するdylib(shared object) を含め、命令をすべてユーザー空間で実行する。
要するに、Apple Silicon以外のx86_64命令で書かれた実行ファイルを翻訳して動かすソフトウェアである。&lt;/p&gt;

&lt;p&gt;実行モード&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;JIT （実行時あるいは動的に命令を翻訳する = 逆アセンブルして解釈されて実行される）&lt;/li&gt;
  &lt;li&gt;AOT（事前あるいは実行前に命令を逆アセンブル・変換しておき、実行時は翻訳済みコードを実行する）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;時間の都合により、今回はJITのみ実装した。&lt;/p&gt;

&lt;h3 id=&quot;設計&quot;&gt;設計&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;ローダー / プロセスの起動&lt;/li&gt;
  &lt;li&gt;デコーダ  + IR リフタ (Lifter)&lt;/li&gt;
  &lt;li&gt;バックエンド（コード生成）&lt;/li&gt;
  &lt;li&gt;ランタイム&lt;/li&gt;
  &lt;li&gt;システム互換層&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;以下Claude Code生成によるコンポーネントの構成を示す。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/a/20260625_pipeline.svg&quot; width=&quot;700&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;プロジェクトの構成&quot;&gt;プロジェクトの構成&lt;/h3&gt;

&lt;p&gt;好みで実装言語にRustを選択。
プログラム名は Rustmute (Rust + transmute)とした。&lt;/p&gt;

&lt;p&gt;crate 構成（これもClaude Codeによる生成）&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-core&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;共通型、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GuestCpu&lt;/code&gt; 状態、ゲストメモリ抽象、エラー型&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-loader&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Mach-O 解析、dyld エミュレーション（依存解決・再配置・束縛）&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-ir&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Rustmute IR 定義、IR ビルダ、最適化パス&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-decoder&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;iced-x86 によるデコード、x86 → IR リフタ&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-arm64&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;ARM64 エンコーダ（dynasm ベース）、共通ロワリング&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-jit&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;JIT エンジン、ブロックキャッシュ、ディスパッチャ&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-aot&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;AOT コンパイラ、翻訳済み Mach-O/オブジェクト出力（未実装）&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-runtime&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;syscall/Mach trap 変換、シグナル、TLS、guest↔host ブリッジ&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustmute-cli&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rustmute run foo&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rustmute compile foo -o foo.arm64&lt;/code&gt;&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;各コンポーネントの依存&quot;&gt;各コンポーネントの依存&lt;/h3&gt;

&lt;p&gt;逆アセンブラ、アセンブラのcrateを依存に追加し利用している。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;rustmute-decoder
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/iced-x86&quot;&gt;iced-x86&lt;/a&gt; … iced-x86 is a blazing fast and correct x86/x64 disassembler, assembler and instruction decoder written in Rust&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;rustmute-arm64
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/dynasm&quot;&gt;dynasm&lt;/a&gt; … A plugin for assembling code at runtime. Combined with the runtime crate dynasmrt it can be used to write JIT compilers easily.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/dynasmrt&quot;&gt;dynasmrt&lt;/a&gt; … A simple runtime for assembling code at runtime. Combined with the plugin crate dynasm it can be used to write JIT compilers easily.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;実装&quot;&gt;実装&lt;/h2&gt;

&lt;p&gt;Claude Codeの生成物ではある。
今回作成のバイナリトランスレータRustmuteがどんな機能を持っているか記す。&lt;/p&gt;

&lt;h3 id=&quot;loader&quot;&gt;Loader&lt;/h3&gt;

&lt;p&gt;実行ファイル及び動的ライブラリであるMach-Oやdylibの読み込みを行う。
ファイル内のセクション、CPUの命令、文字列やテーブルなどの情報を読み込む。&lt;/p&gt;

&lt;p&gt;既存crateを使うか、自作（Claude Code任せ）か迷うところで判断があったが、自動的に自作となった。
自作の利点としてMach-Oの読み込みの際の自由度があがったと認識している。&lt;/p&gt;

&lt;p&gt;覚えておくと良いキーワードとして、VA(Virtual Address)といったものがある（WindowsだとPEフォーマットでRelative Virtual Addressが出たかも）。
ファイル上のオフセットを、ロード後の仮想アドレスに変換する必要がある。&lt;/p&gt;

&lt;p&gt;セキュリティに気を使うならば、これらのファイルヘッダーの数値（サイズ、カウント）の値が過剰なまでに巨大になっていないかチェックしたり、数値の演算でオーバーフローになってないかチェックしてもよさそうである。&lt;/p&gt;

&lt;h3 id=&quot;loader-その2-dyld&quot;&gt;Loader その2 (dyld)&lt;/h3&gt;

&lt;p&gt;macOSのdyld (動的リンカー) を使うことも設計上の選択であった。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;x86_64用にdyldを実装する&lt;/li&gt;
  &lt;li&gt;dyldの代わりに専用のランタイムで処理する（Rosetta 2）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;参考： &lt;a href=&quot;https://support.apple.com/ja-jp/guide/security/secebb113be1/web&quot;&gt;Appleシリコン搭載MacのRosetta 2 - Apple サポート (日本)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;それとは別で、libcなどの関数をホストのRustmute側でラップして呼び出す方式（shim方式）もあったが、今回はRosetta型のsyscall trapの方式を採用することにした。
速度を求めるなら当然libc内部をエミュレートしない方がもちろん速いのだが、今回はそこそこエミュレーションさせたいので私の好みでこうなった。&lt;/p&gt;

&lt;p&gt;macOSの仕組みな話（確信があまりない）。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;dyld … dyld (Dynamic Linker, 動的リンカー) は動的ライブラリをロードする。コード署名などのチェックといった役割も担う。&lt;/li&gt;
  &lt;li&gt;dyld_shared_cache … Appleの主要フレームワークを事前リンクしたキャッシュ。起動の高速化、メモリ節約、シンボル解決の高速化が利点。
ここでmacOSのシステムの解説をしているということはつまり、バイナリトランスレータからx86_64の起動時にmacOSにおけるモジュールロードあたりでOSの知識が必要になってくるわけである。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;キーワード： dylib, mach-o, virtual address, dyld, dyld_shared_cache&lt;/p&gt;

&lt;h3 id=&quot;decoder-その1&quot;&gt;Decoder その1&lt;/h3&gt;

&lt;p&gt;命令のデコード（逆アセンブル）をし、それを後続に渡す。
昔は練習で逆アセンブラを作りかけたが、x86の逆アセンブラは命令が複雑で学習目的に向かないと思う。
当初から逆アセンブラは iced-x86 crate を考えていたが、自動的にこちらが採用となった。&lt;/p&gt;

&lt;p&gt;x86（x64も）は可変長の命令セットのCPUアーキテクチャである。
つまり、1バイトで表現する命令もあれば、2バイト・3バイト…で表現できる命令もあるわけだ。
これは表現したい命令列を短いバイト数で表現できることもあるが、CPUのハードウェアを作るときも、バイナリトランスレータで利用する逆アセンブラを実装するとき命令が固定長のものを作るよりも難しくなる。&lt;/p&gt;

&lt;p&gt;さいわいにも、Rustには iced-x86が存在したので助かったのだが、正確性だけでなく実行速度も速いとは恐れ入る。&lt;/p&gt;

&lt;h3 id=&quot;decoder-その2lifter&quot;&gt;Decoder その2（Lifter）&lt;/h3&gt;

&lt;p&gt;後述するIRという構造（表現）へ、抽象度を上げるのでLift（LiftしているコンポーネントをLifter）と言う。
IRになった段階で、後続(AOT/JIT)のために一部の最適化も実行できるようになる。&lt;/p&gt;

&lt;p&gt;この段階で、実行できる最適化で代表的なものは以下のものがある。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;遅延フラグ除去&lt;/li&gt;
  &lt;li&gt;レジスタの不要なコード除去(DCE, Dead code elimination)&lt;/li&gt;
  &lt;li&gt;定数畳み込み&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ランタイムjitエンジン及びsyscall&quot;&gt;ランタイム・JITエンジン及びsyscall&lt;/h3&gt;

&lt;p&gt;実質ここがプログラムの起点（main）であり、図のように実行ファイルを処理するentrypointとなるプログラムである。&lt;/p&gt;

&lt;p&gt;syscallの実装は、Rustで書かれたlibcを呼び出したりしている。&lt;/p&gt;

&lt;h3 id=&quot;guest--host-ブリッジ&quot;&gt;Guest ↔ Host ブリッジ&lt;/h3&gt;

&lt;p&gt;syscall / Mach trap を境界とし、&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;ユーザー空間のx86コード（メインバイナリ+ dylib）は全てARM64に変換、翻訳して実行&lt;/li&gt;
  &lt;li&gt;カーネルへの問い合わせが必要な瞬間（syscall、Mach trap）だけホストネイティブ(rustmute-runtime)に渡される&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;syscallとMach trapは別々のディスパッチに振り分けられる&lt;/li&gt;
  &lt;li&gt;rustmute-runtimeの命令実行ループ（ランループ）は、syscall/Mach trapに遭遇すると制御を取り戻し、ホスト側ハンドラを実行後、ゲストを再開する。&lt;/li&gt;
  &lt;li&gt;メモリモデル… x86_64とホストの仮想アドレスは1:1マッピングされる。&lt;/li&gt;
  &lt;li&gt;ゲストはx86_64、ホストはARM64なのでゲスト向けに嘘の情報を返すこともある。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;（ここはLLMのコピペ＆Claudeで図を作成）：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;計算ロジックは翻訳済みARM64コードとして完結させたまま、「OS・カーネルとやり取りする瞬間」だけホスト機能を呼び出し、その結果をx86的なレイアウト・値に変換してゲストに返す、というのがブリッジの基本設計です。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/images/a/20260625_guest_host_bridge.svg&quot; width=&quot;750&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;例外シグナルフォールト&quot;&gt;例外／シグナル／フォールト&lt;/h3&gt;

&lt;p&gt;基本&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;ゲストコードが例外（未対応命令、不正アクセス等）に遭遇すると、ランループに制御が戻る。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;シグナル&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;ゲストでの &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sigaction&lt;/code&gt; で登録されたハンドラをホスト側で保持される。&lt;/li&gt;
  &lt;li&gt;同期と非同期シグナルの区別。&lt;/li&gt;
  &lt;li&gt;ランループでホストに制御が戻り、ホスト側のハンドラを実行している。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ページフォールト（ここはLLMのコピペ）：&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  ARM64 生成コード（メモリヘルパ）
    null/OOB アクセス検出
    → PENDING_MEM_FAULT に詰めて即 return（panicしない）
          ↓
  JIT run() ループ（ブロック実行直後、毎回チェック）
    take_pending_mem_fault() で検出
    → get_sig_disp(11) でハンドラ有無を確認（runtime のグローバル表）
          ↓
    ハンドラあり: deliver_signal(11, rip)
      → ゲストスタックに siginfo_t/ucontext_t 構築
      → SIG_RETURN_ADDR を仕込んでハンドラへジャンプ（SyscallResult::Redirect）
      → ハンドラ ret 時に run() が sig_stack から元の文脈を復元
    ハンドラなし: exit(139)  ← 実機の SIGSEGV デフォルト動作を模倣
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;ポイントは、実際の ARM64 MMU フォールト（W^X
  やマップ外アクセス）ではなく、ソフトウェアでの範囲チェックを使って意図的にSIGSEGV相当の状況を作り出している点です。これにより Rust 側で
  panic/unwind することなく、x86ゲストにとって自然な「SIGSEGVが配送される」という観測結果を再現しています。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;mach-trap-machのシステムコール&quot;&gt;Mach trap （Machのシステムコール）&lt;/h3&gt;

&lt;p&gt;macOSはBSD系のUnix syscallだけでなく、 Mach(XNU カーネル)由来のMach trapというシステムコールを持っている。
それをrustmute-runtimeではsyscallと並べてMach trapを処理するコードを書いている。&lt;/p&gt;

&lt;h3 id=&quot;メモリオーダリング-tso&quot;&gt;メモリオーダリング (TSO)&lt;/h3&gt;

&lt;p&gt;時間が足らずTSO(Total Store Ordering)の実装は非対応。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;x86_64 … TSO(Total Store Ordering) を採用&lt;/li&gt;
  &lt;li&gt;ARM64 … 弱いメモリ順序&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;バイナリトランスレーションで、x86_64命令をARM64命令に1対1で変換しているだけだと、ロック処理、並行処理に依存したコードで異なる挙動を示す可能性がある。
そこで、Apple SiliconではTSOにメモリモデルを切り替える命令があるらしい。&lt;/p&gt;

&lt;p&gt;参考:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://yamasa.hatenablog.jp/entry/2020/12/07/041649&quot;&gt;https://yamasa.hatenablog.jp/entry/2020/12/07/041649&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blogs.itmedia.co.jp/appliedmarketing/2021/02/apple_m1_1.html&quot;&gt;https://blogs.itmedia.co.jp/appliedmarketing/2021/02/apple_m1_1.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.sciencedirect.com/science/article/pii/S1383762124000390&quot;&gt;https://www.sciencedirect.com/science/article/pii/S1383762124000390&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/documentation/virtualization/accelerating-the-performance-of-rosetta&quot;&gt;https://developer.apple.com/documentation/virtualization/accelerating-the-performance-of-rosetta&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ir-の設計&quot;&gt;IR の設計&lt;/h3&gt;
&lt;p&gt;IR(Intermediate Representation 中間表現)について説明する。
IRの意義は、バイナリトランスレーションのような異なる表現間（今回はCPUアーキテクチャ。プログラミング言語でもいい）において、共通の意味表現を提供し、今回は命令の実行やコード生成、そして最適化を実現することにある。&lt;/p&gt;

&lt;p&gt;例えば、「x86_64 → IR → JIT(ARM64)」「x86_64 → IR → AOT(実行ファイル)」のように、共通のx86_64から異なるバックエンド（JIT, AOT）を生成するための独自表現として今回のIRは利用される。&lt;/p&gt;

&lt;p&gt;今回のIRコンポーネントは表現の提供以外に、以下の特徴を持っている。&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;フラグの遅延評価 … 後述する「デッドフラグ除去」が可能になる。&lt;/li&gt;
  &lt;li&gt;x86の加減算のように桁上がり下がりのキャリーを保持した細かい表現を、IRで実現している。&lt;/li&gt;
  &lt;li&gt;JIT/AOT 共有 … 一度フロントエンド（decoder）を書けば、JIT/AOT両方で利用できる。&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;最適化のパターン&quot;&gt;最適化のパターン&lt;/h4&gt;

&lt;p&gt;バイナリトランスレーションやJITにおける最適化はいくつかある。
初期実装と、後から実装に加えた物それぞれ示す。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;初期からあるもの
    &lt;ul&gt;
      &lt;li&gt;命令キャッシュ … 逆アセンブルしてARM64コードに変換済みの命令列をキャッシュする。 HashMapで1探索で完了する。アドレス単位で探索。&lt;/li&gt;
      &lt;li&gt;レジスタ読み書きの関数呼び出しを当初していたが、相当する命令に置き換えたことによる高速化。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;後から追加のもの
    &lt;ul&gt;
      &lt;li&gt;デッドフラグ除去 … フラグレジスタへ出力する命令でも、後続でフラグが入力されていない・使われていないなら計算は無駄となる。これをIRレベルで除去する。&lt;/li&gt;
      &lt;li&gt;レジスタのdead code 除去(dead code elimination) … 短時間で終わるプログラムでは最適化が逆に時間を食っているかも。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;今回、実装を見送ったもの
    &lt;ul&gt;
      &lt;li&gt;ブロックチェイニング … 分岐先へ直接ジャンプしてディスパッチ往復を省くもの。自己書き換えコード（SMC）への対応にも追われそうで、修正規模の割に（今回の実験的な実装での）メリットがなく未実装。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;今回実行したファイルは最適化ビルドされたものであるため、バイナリトランスレーション後に最適化が効く余地は狭いのでは、という話もある。&lt;/p&gt;

&lt;h3 id=&quot;実装デバッグのアプローチ&quot;&gt;実装・デバッグのアプローチ&lt;/h3&gt;
&lt;p&gt;主にClaude Codeでのやり方を書くが、人間がやってもおよそ同じやり方をとると思う。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;ローダーやランタイムをギリギリ動かす最低限繋げる／主要な命令（加減算や条件分岐など）も実装する&lt;/li&gt;
  &lt;li&gt;代表的なプログラム（CLIで、echoなど）を動かす&lt;/li&gt;
  &lt;li&gt;未実装のx86_64の命令あるいは実行結果やエラーや正常終了するまで動かす&lt;/li&gt;
  &lt;li&gt;結果（出力、エラー）が出たらデバッグ（命令を実装したり失敗箇所を修正する）／成功したら2で別のプログラムを実行する&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;要は、バグが出なくなるまで色んな実行バイナリを食わせてぐるぐるデバッグと実装を回す方法である。
人間がバイナリトランスレータなりエミュレータなりを実装する時もこんなアプローチだと想像できるが、これは結構Claude Codeと相性が良かった（トークンを消費するが）。&lt;/p&gt;

&lt;h4 id=&quot;動作させた実行ファイル&quot;&gt;動作させた実行ファイル&lt;/h4&gt;

&lt;p&gt;完全動作かは別として、起動・実行を確認した代表例。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;tar, gzip, bzip2, zip, sw_vers, seq, ls, cp, file, sort, curl, textutil&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;開発中は実装不足だったが、最終的にはおおよそ動作するようになった。&lt;/p&gt;

&lt;h2 id=&quot;ベンチマーク&quot;&gt;ベンチマーク&lt;/h2&gt;

&lt;p&gt;md5コマンドの実行時間を紹介する。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ time ./target/release/rustmute run-with-dyld /sbin/md5 /sbin/md5
[dyld-boot] main binary: /sbin/md5  entry=0x100000680  is_lc_main=true
[dyld-boot] dyld: /usr/lib/dyld  entry=0x4e50
[dyld-boot] KernelArgs.mainExecutable=0x100000000
[dyld-boot] shared cache mapped at 0x7ff800000000
[dyld-boot] starting JIT at dyld entry 0x4e50, RSP=0x7fffffdff320
MD5 (/sbin/md5) = 2e26db32e9d772b7c4551c11977e444e

real    0m0.704s
user    0m0.315s
sys     0m0.387s
$ time /sbin/md5 /sbin/md5
MD5 (/sbin/md5) = 2e26db32e9d772b7c4551c11977e444e

real    0m0.006s
user    0m0.002s
sys     0m0.004s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;md5コマンドのファイルは133KBなのでmd5を計算するにしては負荷が小さいく、RustmuteのJITのオーバーヘッドが大きいため、md5計算自体の差は見えない。&lt;/p&gt;

&lt;p&gt;ubuntu-24.04.3-desktop-amd64.iso  (5.9G)を対象にするとmd5コマンドで12.560s,、rustmuteで306.697s 純粋にCPU負荷のワークロードではまだまだ遅い。&lt;/p&gt;

&lt;p&gt;isoイメージは大きすぎたので適当なepub(300MB近い)を使って、実行時間も計測した。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rustmute timings [run-with-dyld]:
  load        :      0.1 ms
  stack-setup :      0.0 ms
  cache-map   :    165.1 ms
  lift        :      7.3 ms   (13699 calls)
  codegen     :    121.0 ms   (13699 calls)
  execute     :  13242.5 ms   (57331408 calls)
  syscall     :    134.7 ms   (73929 calls)
  ───────────────────────────────────
  measured    :  13670.8 ms
  total wall  :  16309.3 ms
  block cache:
    hot hit    :   57317709  (99.98%)
    slow hit   :          0  ( 0.00%)
    cold miss  :      13699  ( 0.02%)
    smc        :          0  ( 0.00%)
    ─ total    :   57331408
  dispatch exits:
    jump       :   57257479  (99.87%)  ← chainable
    syscall    :      73929  ( 0.13%)
    ret        :          0  ( 0.00%)
    trap       :          0  ( 0.00%)
    ─ total    :   57331408  (== execute ✓ )
  chaining estimate:
    loop overhead  :   46.0 ns/iter
    potential save : 2635.2 ms  (= jump × overhead)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;改善&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Rustの &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::time::Instant&lt;/code&gt; をコンポーネントの各フェーズに仕込み、実行時間を見えるようにした。&lt;/li&gt;
  &lt;li&gt;変換した命令のブロックキャッシュにhit/missカウンタを追加した。&lt;/li&gt;
  &lt;li&gt;ブロックチェイニングの最適化が有効化どうかを出力させた。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;今回は結果がすぐ欲しくて雑にカウンタを追加しちゃった（Claudeの言いなり）。&lt;/p&gt;

&lt;p&gt;実行結果は想像通り、md5アルゴリズムの実行であるから変換した命令（execute）の実行時間と実行回数が明らかに大きい。
命令の変換自体はオーバーヘッドとしては小さいことがわかる。
こういう結果を見ながら最適化をしてみたいものである。&lt;/p&gt;

&lt;p&gt;参考 - Hot hit, Slow hit, Cold miss
&lt;img src=&quot;/images/a/20260625_hot_hit_slow_hit_cold_miss.svg&quot; width=&quot;700&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;バイナリトランスレータの設計、実装についてまとめた。
実装の詳細は多く省いたが、内部構造の理解の助けになれば幸いである。&lt;/p&gt;

&lt;h3 id=&quot;書いてない技術トピック&quot;&gt;書いてない技術トピック&lt;/h3&gt;

&lt;p&gt;Claude Code（コーディングエージェント）の力を借りて実装したわけだが、乗り越える必要のあった技術課題、コンピュータアーキテクチャの専門分野がいくつもあったはずである。
書き残しておきたいトピックはここで取り上げる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;仮想メモリの実現方法&lt;/li&gt;
  &lt;li&gt;プロファイル
    &lt;ul&gt;
      &lt;li&gt;ベンチマークのところで少し取り上げたが、Rustmuteの各機能ごとの実行時間の測定。これによりオーバーヘッドの切り分けも可能になる。&lt;/li&gt;
      &lt;li&gt;キャッシュの性能、ヒット率、ミス数の計測。次に実行する最適化の有効性を確認することもできる。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;将来の展望&quot;&gt;将来の展望&lt;/h3&gt;

&lt;p&gt;試しに作ったバイナリトランスレータであるが、意外とCLIなどはサクサク動いたのであった。
色んな制約から今すぐは実装しないが、作ると面白そうなものを次にあげる。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;アンチウイルスのサンドボックス&lt;/li&gt;
  &lt;li&gt;フロントエンドでのARM64命令の対応&lt;/li&gt;
  &lt;li&gt;開発ツール（Valgrindもどき、プロファイラ、仮想マシン技術を応用して何か）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;バイナリトランスレーションがなければ、ほぼx86_64向けエミュレータ兼macOS ローダー及びランタイムである。&lt;/p&gt;

&lt;p&gt;コーディングエージェントでソフトウェアが簡単に作れる時代ではあるが、設計とアーキテクチャ学習を繰り返し、人の手でアイディアやPoCの実現を加速させたい。&lt;/p&gt;

&lt;h3 id=&quot;ウェブ上の資料&quot;&gt;ウェブ上の資料&lt;/h3&gt;

&lt;p&gt;まずは基本的（公式あるいはWikipedia）の資料に頼るつもりで、他の資料に頼らず作成、執筆した。
参考にはなるはず。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ffri.github.io/ProjectChampollion/&quot;&gt;https://ffri.github.io/ProjectChampollion/&lt;/a&gt; … reverse-engineering results of Rosetta 2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Inokinoki/attesor&quot;&gt;https://github.com/Inokinoki/attesor&lt;/a&gt; … AI-powered reverse-engineering of Rosetta (2 for Linux). Disclaimer: due to the user agreement, I will not touch the code. All is done by AI, so there might be messy implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;キーワード&quot;&gt;キーワード&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;shim 方式 … ゲストがライブラリやシステムコールを呼ぶ際に、ホストの薄いラッパーを呼ぶ方式のことをこう言うとか（ウェブで資料が出てこない）&lt;/li&gt;
  &lt;li&gt;SMC(Self-Modifying Code): 自己書き換えコードのこと。実行時にプログラムがCPUの命令を生成したり、命令にパッチをあてたりすることがある。例えばパフォーマンス目的で、今回のようにJITコンパイラなどを作る場合。また、アンチデバッグ技術として実行ファイルの解析をしづらくさせるために自己書き換えを行うこともある。&lt;/li&gt;
  &lt;li&gt;Lift, Lifter:  上位へ持ち上げるという意味で、機械語→ IR などが例となるらしい。逆方向がLower。&lt;/li&gt;
  &lt;li&gt;Lower:  Lift, Lifterとは逆に IR → 機械語というようにより低レイヤのこと。ロワリングは低レイヤへ変換すること。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;おまけ---コード行数&quot;&gt;おまけ - コード行数&lt;/h3&gt;

&lt;details&gt;
  &lt;summary&gt;create内のコード行数の一覧&lt;/summary&gt;

  &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;find crates/ &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.rs&quot;&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
     107 crates/rustmute-jit/tests/dynlink.rs
     119 crates/rustmute-jit/tests/threads.rs
    2622 crates/rustmute-jit/src/lib.rs
     255 crates/rustmute-jit/src/futex.rs
     159 crates/rustmute-ir/src/types.rs
     261 crates/rustmute-ir/src/flags.rs
      25 crates/rustmute-ir/src/lib.rs
     107 crates/rustmute-ir/src/block.rs
    1148 crates/rustmute-ir/src/instr.rs
    1083 crates/rustmute-interp/tests/interp_basic.rs
     292 crates/rustmute-interp/src/flags.rs
      10 crates/rustmute-interp/src/lib.rs
     869 crates/rustmute-interp/src/interp.rs
     173 crates/rustmute-arm64/src/flag_dce.rs
     575 crates/rustmute-arm64/src/regalloc.rs
      79 crates/rustmute-arm64/src/lib.rs
     886 crates/rustmute-arm64/src/helpers.rs
     125 crates/rustmute-arm64/src/abi.rs
    1857 crates/rustmute-arm64/src/lower.rs
      21 crates/rustmute-aot/src/lib.rs
     223 crates/rustmute-runtime/tests/execution.rs
     233 crates/rustmute-runtime/src/native.rs
    2912 crates/rustmute-runtime/src/lib.rs
     444 crates/rustmute-runtime/src/shims.rs
    1054 crates/rustmute-decoder/tests/lift.rs
    3208 crates/rustmute-decoder/src/lifter.rs
      10 crates/rustmute-decoder/src/lib.rs
     140 crates/rustmute-decoder/src/regmap.rs
     339 crates/rustmute-cli/src/main.rs
     168 crates/rustmute-cache/tests/parse_x86_cache.rs
      22 crates/rustmute-cache/examples/symbolize.rs
      27 crates/rustmute-cache/src/error.rs
     128 crates/rustmute-cache/src/lib.rs
     128 crates/rustmute-cache/src/header.rs
     197 crates/rustmute-cache/src/exports.rs
      95 crates/rustmute-cache/src/image.rs
      87 crates/rustmute-cache/src/mapping.rs
     557 crates/rustmute-core/src/cpu.rs
      46 crates/rustmute-core/src/error.rs
      13 crates/rustmute-core/src/lib.rs
     482 crates/rustmute-core/src/memory.rs
     199 crates/rustmute-loader/tests/load_macho.rs
      24 crates/rustmute-loader/examples/disas.rs
      15 crates/rustmute-loader/examples/readstr.rs
     235 crates/rustmute-loader/src/cache.rs
      20 crates/rustmute-loader/src/lib.rs
     338 crates/rustmute-loader/src/macho.rs
     326 crates/rustmute-loader/src/dyld.rs
     123 crates/rustmute-loader/src/fat.rs
     240 crates/rustmute-loader/src/stack.rs
     295 crates/rustmute-loader/src/loader.rs
     124 crates/rustmute-loader/src/shims.rs
   23225 total
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/details&gt;
</description>
        <pubDate>Thu, 25 Jun 2026 23:00:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2026/06/25/design-and-implementation-binary-translator.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2026/06/25/design-and-implementation-binary-translator.html</guid>
        
        
      </item>
    
      <item>
        <title>バイナリエディタPheasant v0.1.0 リリース</title>
        <description>&lt;p&gt;バイナリエディタPheasant v0.1.0をリリースしました。&lt;/p&gt;

&lt;h2 id=&quot;1-これは何か&quot;&gt;1. これは何か&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/p/20260323_screenshot.gif&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;PheasantはRust製のバイナリエディタで、GPUアクセラレーション描画で大規模ファイルも軽快に動作可能です。
Claude Codeでコードを生成して作りましたが、設計だけでなく実装レベルでレビューが入っています。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/suma/rusthex/releases/&quot;&gt;https://github.com/suma/rusthex/releases/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;2-なぜ作ったか&quot;&gt;2. なぜ作ったか&lt;/h2&gt;

&lt;p&gt;近年だとリッチな機能を持つバイナリエディタもありますが、私がバイナリエディタを作ろうと思ったのは約20年前にもさかのぼります。&lt;/p&gt;

&lt;p&gt;大きなファイルでの動作速度を確保し、クロスプラットフォームに対応したエディタ当時は珍しかったのです。&lt;/p&gt;

&lt;p&gt;そういう理由でアイディアは持っていたものの、過去に開発途中で投げだしたことはあり、Claude Code (Opus 4.5)の出現によって再度開発するモチベーションがわいてきました。2025年12月のことです。
自分用とはいえ半分趣味ではあります。&lt;/p&gt;

&lt;h2 id=&quot;3-pheasantの主な機能&quot;&gt;3. Pheasantの主な機能&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;ファイルを眺める&lt;/strong&gt;: 巨大ファイル対応（メモリマップ）、ビットマップ可視化で全体の構造を俯瞰
    &lt;ul&gt;
      &lt;li&gt;巨大なファイル対応は、Piece Tableと呼ばれるデータ構造でドキュメントを表現します。これにより巨大なファイルの挿入、削除、上書きに対応しつつも、高速な画面のスクロールも可能になります。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;検索・ナビゲーション&lt;/strong&gt;: マルチスレッドでUIとは別スレッドで高速検索、ワイルドカード対応、ブックマーク機能
    &lt;ul&gt;
      &lt;li&gt;モダンなエディタっぽく仕上げるために、検索だけでなくブックマークやカーソルの履歴も保持するようにしました。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AI連携&lt;/strong&gt;: 選択範囲をOllamaなど外部コマンド(LLM)にパイプして解析可能、MCPサーバーでClaude Codeから直接バイナリ操作
    &lt;ul&gt;
      &lt;li&gt;かなり実験的な機能で、今後どうなるか未定ですがLLMと接続してバイナリエディタ自身を拡張できるようにしています。といっても現段階ではログ画面に解析結果を表示するだけとなっています。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/p/20260323_pheasant.png&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;4-aiとの連携&quot;&gt;4. AIとの連携&lt;/h2&gt;

&lt;p&gt;AI(LLM)を用いたバイナリ解析というのは今後主要なトピックになっていくと考えています。
そんな中、バイナリエディタとしてできるアプローチとしては次の2点が筋が良いと思っています。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;外部のLLMをエディタから呼び出す&lt;/strong&gt; 前述したOllama連携(外部コマンド呼び出し)がこれです。
    &lt;ul&gt;
      &lt;li&gt;どうしてもバイナリエディタ側の機能は少なくなる、あるいはPython拡張のようなアプローチにせざるを得ない状況になるのではないかと思います。そんな中、LLMは光明かもしれません。少なくとも現状は、「ヒント」を外部からもらうためのインターフェースとしてコマンドラインで外部にデータ解析を投げるだけです。解析する主体は人間にあります。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MCPサーバー&lt;/strong&gt; LLM側からバイナリデータを読み書き、解析するというアプローチです。
    &lt;ul&gt;
      &lt;li&gt;これはもう解析の自動化、あるいは解析する主体を人間(バイナリエディタ)から機械(LLM)へ移すという流れになります。現在のLLMの流行を考えると、こちらのアプローチも強くした方がいいかもしれません。実験的な機能なため、ドキュメントもあえて整備していません。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;5-今後の予定&quot;&gt;5. 今後の予定&lt;/h2&gt;

&lt;p&gt;バイナリ解析はどうなってしまうのか、という情勢ではありますが、まずは気軽に解析するためのアプローチとしてこちらのバイナリエディタPheasantを触ってもらえると嬉しいです。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/suma/rusthex/releases/&quot;&gt;https://github.com/suma/rusthex/releases/&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Mar 2026 13:21:20 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2026/03/23/pheasant.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2026/03/23/pheasant.html</guid>
        
        
      </item>
    
      <item>
        <title>2025年を振り返りつつ、2026年やりたいこと</title>
        <description>&lt;h1 id=&quot;あっという間に2026年&quot;&gt;あっという間に2026年&lt;/h1&gt;

&lt;p&gt;2025年を振り返りつつ2025年やりたいこと、学習したいことについて書く。&lt;/p&gt;

&lt;h2 id=&quot;2025年で買って良かったもの&quot;&gt;2025年で買って良かったもの&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Technicsのイヤホン  EAH-AZ100&lt;/li&gt;
  &lt;li&gt;組立代行へ発注したPC
    &lt;ul&gt;
      &lt;li&gt;Radeon RX 9070 XTの発売にあわせたが、今のRAM不足を考えると、値下がり具合も含めタイミングが良かった&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;ひげ脱毛を始めた（物ではないが）
    &lt;ul&gt;
      &lt;li&gt;日々の生活でのひげそりが格段に楽になった（肌荒れも減少）&lt;/li&gt;
      &lt;li&gt;少し若返った印象&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;読んで良かった本&quot;&gt;読んで良かった本&lt;/h2&gt;
&lt;p&gt;昨年もその傾向はあったが、集中力、読むスピードは明らかに鈍くなったなという印象。年かな。&lt;/p&gt;

&lt;p&gt;心に残っている本をこちらにリストアップする。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;『メダリスト』
    &lt;ul&gt;
      &lt;li&gt;情熱を感じる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;『時計の科学　人と時間の５０００年の歴史』&lt;/li&gt;
  &lt;li&gt;『世界一わかりやすい腕時計のしくみ』
    &lt;ul&gt;
      &lt;li&gt;某友人が機械式腕時計にハマっていて、話を聞いたりして私は機械式の仕組みに興味を持った&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;『ソフトウェアエンジニアガイドブック』
    &lt;ul&gt;
      &lt;li&gt;キャリアもそうだし、ソフトウェアエンジニアとして技術のキャッチアップにも良さそう&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;書籍ではないが、映画の「国宝」は良かった（2025年ベスト映画）。&lt;/p&gt;

&lt;h2 id=&quot;2025年やったこと行った場所&quot;&gt;2025年やったこと、行った場所&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;6月 大阪・関西万博へ&lt;/li&gt;
  &lt;li&gt;9月 星景写真を撮影しに神津島へ旅行&lt;/li&gt;
  &lt;li&gt;LLM（生成AI）のコーディングエージェントが活躍（私的にも業務でも）
    &lt;ul&gt;
      &lt;li&gt;2025年は生成AIが大躍進した年だと思う&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;コンパイラ学習（実装）を進めることができた。
    &lt;ul&gt;
      &lt;li&gt;今まではパーサーの実装途中だったが、Claude Codeにより言語としてのフロントエンドの部分に加えて、インタプリタの実装も進められた&lt;/li&gt;
      &lt;li&gt;コーディングエージェント（Claude Code）の働きが大きい&lt;/li&gt;
      &lt;li&gt;フロントエンド（主にパーサー部分）にこだわるつもりはなかったが、想像以上に力を入れてしまった&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2026年挑戦したいこと&quot;&gt;2026年挑戦したいこと&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;コンパイラ最適化について学ぶ
    &lt;ul&gt;
      &lt;li&gt;2026年は友人とオンラインで一緒に学習する集まりを開くことになった&lt;/li&gt;
      &lt;li&gt;欲しいアウトプット
        &lt;ul&gt;
          &lt;li&gt;コンパイラのコード生成器を実装する&lt;/li&gt;
          &lt;li&gt;学習した結果をまとめる（ブログなど）&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;継続してコンパイラの実装活動
    &lt;ul&gt;
      &lt;li&gt;アウトプット
        &lt;ul&gt;
          &lt;li&gt;ブログ、実装の公開（GitHub）&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 03 Jan 2026 13:20:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2026/01/03/resolutions-2026.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2026/01/03/resolutions-2026.html</guid>
        
        
      </item>
    
      <item>
        <title>ウェブサーバーでBrotli圧縮を有効化した</title>
        <description>&lt;h1 id=&quot;はじめに&quot;&gt;はじめに&lt;/h1&gt;
&lt;p&gt;ちょっと前に次のエントリを読んだ。Zstandardは知っていたが、Brotliという圧縮アルゴリズムはその時知らなかった。BrotliもZstandardもどちらももう10年近く前に発明された圧縮アルゴリズムになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://zenn.dev/tomoyaf/articles/3d1383603db6a9&quot;&gt;圧縮アルゴリズム比較: gzip・Deflate・Brotli・Zstdの実用性と進化&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;静的ページなので事前圧縮を採用&quot;&gt;静的ページなので事前圧縮を採用！&lt;/h2&gt;
&lt;p&gt;せっかくなので、このobfuscatism.netをホストしているウェブサーバーもBrotli対応しようと考えた。
調査した結果、静的ページしかないので次の前者を選んだ&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;あらかじめファイルを圧縮(pre-compression)しておき、アクセスがあったとき圧縮済みのファイルを転送させる。静的ページに有効&lt;/li&gt;
  &lt;li&gt;Apacheでのmod_gzipのように、動的にアクセスされたファイルを圧縮して転送する。mod_brotli（&lt;a href=&quot;https://httpd.apache.org/docs/current/mod/mod_brotli.html&quot;&gt;Apache&lt;/a&gt;）や、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brotli on;&lt;/code&gt;（&lt;a href=&quot;https://docs.nginx.com/nginx/admin-guide/dynamic-modules/brotli/&quot;&gt;nginx&lt;/a&gt;）オプションなどがある&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;後者は動的コンテンツなどに有効であるが、オンザフライで圧縮がかかる（圧縮済みのデータはキャッシュされないはず）ため静的コンテンツのみの場合にCPUリソースを余計に消費してしまう。&lt;/p&gt;

&lt;p&gt;Claude AI曰く、最低1KB以上のファイルが圧縮に適しているらしい。小さすぎるとオーバーヘッドが大きいというのもなんとなくわかる。&lt;/p&gt;

&lt;h2 id=&quot;apache-24に適用&quot;&gt;Apache 2.4に適用&lt;/h2&gt;
&lt;p&gt;静的コンテンツの場合、mod_rewrite などでリクエストを書き換えたりしたのであるが（gzipで伝統的なやり方の様子）、mod_filterで &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddOutputFilterByType DEFLATE&lt;/code&gt; といったファイルを他より先に圧縮していて中々Brotli圧縮済みのファイルが転送されずに困るといいうこともあった。
最終的には無事Brotliも有効化できた。&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Chromeの開発ツールなどを見て、Brotli圧縮済みのファイルが転送されていたり、転送速度も確認できて満足だった。
しかし、obfuscatism.net自体すごく軽いウェブサイト、ブログなのでgzipで事足りるという説もある 😇&lt;/p&gt;

&lt;p&gt;ほぼ自己満足ではあるが、採用できて良かった。爆速になったかは定かではない。。。&lt;/p&gt;
</description>
        <pubDate>Sun, 07 Dec 2025 23:50:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2025/12/07/web-compression.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2025/12/07/web-compression.html</guid>
        
        
      </item>
    
      <item>
        <title>言語処理系を作っていたとき考えていたこと</title>
        <description>&lt;h1 id=&quot;はじめに&quot;&gt;はじめに&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;/2025/09/10/toylang.html&quot;&gt;Rustで言語処理系を作ってみるという試み&lt;/a&gt; の続きである。
どこにこだわり、どういう理由でそんなプログラミング言語の文法及び実装にしたのかということについて記述する。&lt;/p&gt;

&lt;h2 id=&quot;設計こだわりポイント&quot;&gt;設計、こだわりポイント&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;言語
    &lt;ul&gt;
      &lt;li&gt;静的型付け言語&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;syntax
    &lt;ul&gt;
      &lt;li&gt;Go, Python風に改行で1文を区切る&lt;/li&gt;
      &lt;li&gt;if/else/whileなどの条件の括弧&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;()&lt;/code&gt; は省略したい
        &lt;ul&gt;
          &lt;li&gt;GoとかRust風&lt;/li&gt;
          &lt;li&gt;追加のトレードオフ： &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if variable_name {&lt;/code&gt; の &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;variable_name {&lt;/code&gt; が構造体リテラルに誤認識してしまった。パーサーの追加修正あり&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;if/elseには必ず &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt; を付ける
        &lt;ul&gt;
          &lt;li&gt;追加のトレードオフ
            &lt;ul&gt;
              &lt;li&gt;elifキーワード (else if)の導入&lt;/li&gt;
              &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if x {} else { if y {} }&lt;/code&gt; のようなコードを防ぐため&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;型推論
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var&lt;/code&gt; の型宣言を省略可能。また、後続の変数（代入など）から型推論できる&lt;/li&gt;
          &lt;li&gt;Rustっぽいですね&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;エラー処理
        &lt;ul&gt;
          &lt;li&gt;文法や型チェックでエラーが出たとき、エラーの位置を表示できる&lt;/li&gt;
          &lt;li&gt;エラーレポートの表示（行番号、位置）&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;内部構造
    &lt;ul&gt;
      &lt;li&gt;パーサーでは再帰を多用しているが、無限再帰に陥る可能性がある。無限再帰予防の措置（カウントしている）がある&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/String_interning&quot;&gt;String interning&lt;/a&gt;の利用。ソースコード中には、変数や関数などのidentifier、文字列リテラルなどあらゆるところでキーワードトークン以外の文字列が出てくる。そこで、文字列はSymbol(int型とか)で表現することで格納・比較がやりやすくなる。メモリ消費量も抑える（可能性がある）ことができてお得だ。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;将来
    &lt;ul&gt;
      &lt;li&gt;エラー処理のためにトークン及びASTレベルでコードの位置情報を保持しているが、LSP対応とかlinterとか考えると保持する利点はありそうである。&lt;/li&gt;
      &lt;li&gt;Frontendは並列化（マルチスレッド化）したいとかそういう野望もある。現状は、String interningや型チェック時のシンボル探索などをどう並列化するとよいか考え中でもある。しかしClaude Codeがサクッと答えを出してきそうなポイントでもある。
        &lt;ul&gt;
          &lt;li&gt;Claude Codeによると、Rust (rustc), TypeScript Compiler (tsc), Go Compiler - パッケージレベル, Swift Compiler - ファイルレベル などで並列化をサポートしているらしい。&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;実装コンポーネントレベルのはなし&quot;&gt;実装・コンポーネントレベルのはなし&lt;/h2&gt;

&lt;p&gt;Rustの実装レベル、コンポーネントレベルでどのようにしているか書く。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Lexer
    &lt;ul&gt;
      &lt;li&gt;以下のトークンに分割するのがLexerの役目。
        &lt;ul&gt;
          &lt;li&gt;キーワード、コメント、数値リテラル、文字列リテラル&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;すべてのトークンは文字列の位置情報を持っている。たしか、ソースの文字列の開始位置とその長さを持っていたと思う。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Parser
    &lt;ul&gt;
      &lt;li&gt;当初はすべて手書きだったが、気づいたらClaude Codeに書き換えられていた。ちょっとむなしい。&lt;/li&gt;
      &lt;li&gt;再帰下降パーサーであるが、再帰の箇所では上に書いたように再帰回数のカウントがあり、スタックオーバーフロー防止になっている。Claude Codeの実装になるのと、そんな難しいアイディアではないが初出はどこだろうね。&lt;/li&gt;
      &lt;li&gt;文法エラーの複数取得は意外と簡単なところもあり、次に出現するトークン（予定）と違ったらエラーではあるが、そこはエラーは無かったことにして後続の処理へ続けさせ、1個でもエラーが貯まっていれば文法エラーがあると判別できる（理論上は、、、もうちょっと難しかったかもしれない）。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;TypeChecker
    &lt;ul&gt;
      &lt;li&gt;TypeCheckerという仰々しい名前ではあるが、以下の機能も行っている。
        &lt;ul&gt;
          &lt;li&gt;型チェック&lt;/li&gt;
          &lt;li&gt;変数の存在管理（寿命、スコープ）&lt;/li&gt;
          &lt;li&gt;モジュールのインポートとそのシンボル管理&lt;/li&gt;
          &lt;li&gt;ビルトインのモジュール・関数の提供&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Backend
    &lt;ul&gt;
      &lt;li&gt;Interpreter (走査=walkで、AST walk interpreterと言う分類らしい)
        &lt;ul&gt;
          &lt;li&gt;バックエンドを実装したとき、モデルケースとなる正解のインタプリタがあると便利だろうと思い作成した。&lt;/li&gt;
          &lt;li&gt;実際のところ、自分では使わないがテストを作って実行するのに非常に役に立つ存在となった。また、ベンチマークにもよく使っている。&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Lua backend
        &lt;ul&gt;
          &lt;li&gt;作りかけ。luaファイル（テキスト）を生成する&lt;/li&gt;
          &lt;li&gt;特にLua JITではビット演算のオペレーターがなかった（たぶん）ため、ビット演算をLua JIT提供のライブラリを使うことができるようにした。もしくは、Lua標準の機能を使うか、コード生成時にを使うか切り替え可能なバックエンドにしている&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;雑に整理してみたが、こんなことを考えたり試行錯誤しながら実装していた。&lt;/p&gt;

</description>
        <pubDate>Thu, 11 Sep 2025 20:40:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2025/09/11/toylang_part2.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2025/09/11/toylang_part2.html</guid>
        
        
      </item>
    
      <item>
        <title>Rustで言語処理系を作ってみるという試み</title>
        <description>&lt;h1 id=&quot;はじめに&quot;&gt;はじめに&lt;/h1&gt;

&lt;p&gt;Rustでプログラミング言語の処理系（toylang：名前は未定のまま引きずっている）を作成した。
厳密には作成途中ではあるが、その経過や設計について書きたいと思う。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/suma/toylang&quot;&gt;https://github.com/suma/toylang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最初に断っておくと、私はプログラミング言語や型システムの専門家ではない。アマチュアである。
また、これは趣味の活動によって開発された（厳密には、「されている」）ソフトウェアである。業務で開発した物ではない。&lt;/p&gt;

&lt;p&gt;趣味とはいえ、私はソフトウェアエンジニアとしてのプロの経歴が10年以上になる。
実装レベルで手抜きをしてしまってる箇所も幾分あるが、今回作成した処理系の設計・デザインチョイスといった部分では、こだわり・挑戦してみたいことなどを優先している。といっても、試行錯誤のひとつなので特別お気に入りでない限り特筆しない。
また、こだわりだけではいっこうに開発が進まなかったため、実用レベルのソフトウェアを開発する気概を持ちつつも、途中からClaude Codeの利用が始まると妥協を多く入れていった。まぁ、何しろ言語処理系を作るのはかなり筋肉（と表現させてもらう）が要るからね…。&lt;/p&gt;

&lt;h2 id=&quot;作った言語について&quot;&gt;作った言語について&lt;/h2&gt;

&lt;p&gt;言語仕様は、Rust, Go, Pythonなどからいいとこ取り、気に入った文法や機能を試しに実装している段階にある。繰り返しになるが、まだ開発中である。&lt;/p&gt;

&lt;p&gt;将来的にはLLVMバックエンドなど作りたいところであるが、いまはフロントエンドやインタプリタを作って動作確認・お試しをしている段階にある。&lt;/p&gt;

&lt;p&gt;フロントエンドは何でもよいとか、LLMで生成するからなどという説があるかもしれないが、UXであるとか、DSLとしての使い方など、見た目（文法）はこだわれるポイントである。
LLM（コーディングエージェント）が存在するからといって、オフライン環境ではローカルLLMが必要になるだろうし、ネット上に存在しないハードウェアのソフトを実装するとしたらどうなるだろうか。&lt;/p&gt;

&lt;h2 id=&quot;スタート地点-rflex&quot;&gt;スタート地点 rflex&lt;/h2&gt;
&lt;p&gt;詳しくは &lt;a href=&quot;/2024/02/15/compiler.html&quot;&gt;Rustでコンパイラ作り part1&lt;/a&gt;に譲るが、自作のコンパイラを作りたいと2019年頃から考えていた。
その頃からパーサは手書きにすると決めていたため、せめてLexer生成器だけは自動生成にしようと&lt;a href=&quot;https://crates.io/crates/rflex&quot;&gt;rflex&lt;/a&gt;を作成した。&lt;/p&gt;

&lt;h2 id=&quot;再帰下降パーサとflatten-ast&quot;&gt;再帰下降パーサとFlatten AST&lt;/h2&gt;
&lt;p&gt;再帰下降パーサを書く時点からFlatten ASTな形式であると決めていた。
ふつうAST（抽象構文木）を木構造で表現するが、実装上は配列に格納する形としていた。木構造を表現しなくていいため、そのためのオーバーヘッドや、配列形式によるメモリキャッシュの活用が想定された。&lt;/p&gt;

&lt;p&gt;再帰下降パーサで文法を記述するのに、約2,3年はかかった。
理由は難しかったからではなく、実装の手間が大きかったことによる。
文法が定まってない間は、よい子は余り真似しない方がいいかもしれない。&lt;/p&gt;
&lt;h2 id=&quot;転換点-1-claude-code&quot;&gt;転換点 1. Claude Code&lt;/h2&gt;
&lt;p&gt;再帰下降パーサで文法をおおよそ定義出来てきた頃、Claude CodeなどのAIエージェント（コーディングエージェント）が流行りだした。
これは良いと私も採用を決定し、手書きのフロントエンド（再帰下降パーサ、型チェッカー）などの書き換えが進んでいった。
インタプリタもほぼClaude Codeを利用した気がするし、README.mdもである。&lt;/p&gt;

&lt;p&gt;LLM(Claude Code)の利用テクニックはここで書いても仕方ないと思うが、気にしていた点として、以下の点があげられる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;コンテキストは長く持たない（ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/clear&lt;/code&gt; コマンドを利用する）&lt;/li&gt;
  &lt;li&gt;コードが複雑になる前にリファクタリングをする&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.anthropic.com/ja/docs/claude-code/sub-agents&quot;&gt;サブエージェント&lt;/a&gt; の活用(git-add, git-commitを作成した)&lt;/li&gt;
  &lt;li&gt;Enter連打（あるいは自動）でコードを入力させ、早く実行させたくなるが、Claude Codeが作成したコードの意味をなるべくたずねる、設計上の選択を聞く、オススメの選択を聞くといった行動をとること
    &lt;h2 id=&quot;転換点-2-structure-of-arrays&quot;&gt;転換点 2. Structure of Arrays&lt;/h2&gt;
    &lt;p&gt;SNS上でData Oriented DesignとZig言語、その実装パターンであるStructure of Arraysに感銘を受け、ASTのデータの持ち方をFlatten ASTから変更した。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/IroPQ150F6c?si=0Q9KQitCH3nKqu-5&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;リファクタリングにもClaude Codeを使った。
フロントエンドのパース、型チェックの速度はベンチマーク上で約20倍にもなったので驚愕した。
正直なところ実用的なコードが無い以上、ここでベンチマークの結果についてあれこれ語っても仕方ない面もあるが、コンパイラという種類のソフトウェアの設計（実装パターン）でさえ10倍以上の速度差が出ることについて、やっぱりソフトウェア開発は面白いなと思った。&lt;/p&gt;

&lt;h2 id=&quot;まとめ現在未来&quot;&gt;まとめ（現在・未来）&lt;/h2&gt;

&lt;p&gt;こだわりの機能としては、&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;配列のスライス (絶対欲しい人がいる、自分では使わないがそう思った)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;お試しで作ってみたのは、&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Lua backend&lt;/li&gt;
  &lt;li&gt;Generics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude Codeの甘言に乗せられてしまい、関数と構造体にGenerics機能を追加してしまった。型チェッカーが重くなり、型推論も時間がかかっているはずである。&lt;/p&gt;

&lt;p&gt;本当はこだわりポイントとか語って気持ちよくなろうと思っていたが、表層をなぞるだけで自分がお腹いっぱいになってしまった。
本当にプログラミング言語として成功するには、FFIやツールチェインも必要そう。もしくは、ゲームエンジンに採用されるようなアプローチ（としてLua backendありかなと試しに作った）も考えられるかもしれない。&lt;/p&gt;

&lt;p&gt;まとめると、まずは自分が心地よいコードを書けて、なおかつ近年の研究&lt;a href=&quot;https://x.com/suma90h/status/1962044662744813995/photo/1&quot;&gt;課題&lt;/a&gt; などもアプローチできるとなお面白いんじゃないかと思う。&lt;/p&gt;

&lt;h3 id=&quot;課題&quot;&gt;課題&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;言語組み込みの関数、クラスを作るのは課題である
    &lt;ul&gt;
      &lt;li&gt;なるべく楽に言語処理系内に組み込みたいというモチベーション&lt;/li&gt;
      &lt;li&gt;FFIを上げたが、外部ライブラリとの連携も肝である&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;研究っぽい難しい課題にチャレンジするとなお面白いかも&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;

&lt;h2 id=&quot;ウェブ&quot;&gt;ウェブ&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cs.cornell.edu/~asampson/blog/flattening.html&quot;&gt;Flattening ASTs (and Other Compiler Data Structures)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tech.cygames.co.jp/archives/2843/&quot;&gt;データ指向設計 Cygames Engineers’ Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;書籍&quot;&gt;書籍&lt;/h2&gt;

&lt;p&gt;他にもたくさん書籍はあるが、開発中に読んだものとして、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Rustで作るプログラミング言語 —— コンパイラ／インタプリタの基礎からプログラミング言語の新潮流まで&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;続編&quot;&gt;続編&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/2025/09/11/toylang_part2.html&quot;&gt;言語処理系を作っていたとき考えていたこと&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Wed, 10 Sep 2025 23:40:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2025/09/10/toylang.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2025/09/10/toylang.html</guid>
        
        
      </item>
    
      <item>
        <title>2024年振り返りと、2025年やりたいこと</title>
        <description>&lt;h1 id=&quot;2025年目前&quot;&gt;2025年目前&lt;/h1&gt;

&lt;p&gt;今年も色々ありました。
たいしたことはないけど、プラモデル（ホワイトグリント）を組み立てたり、業務では引き続きウェブサービス開発をやったり、年末には業務に関係なく色彩検定3級を合格したりしました。&lt;/p&gt;

&lt;h2 id=&quot;目標の達成具合&quot;&gt;目標の達成具合&lt;/h2&gt;

&lt;p&gt;以下上2つは2024年の目標だった。
これを含めて2025年は継続しつつ色彩検定の学習もやっていきたい。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ピアノ練習 10-30分（継続）
    &lt;ul&gt;
      &lt;li&gt;毎日のうちたまに忘れることもあるが、ほぼほぼやってる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;週2回、土曜と水曜のジョギング（あるいは片方を筋トレ） 10-30分
    &lt;ul&gt;
      &lt;li&gt;これも完全に習慣化できてるわけではないが、ウォーキングを混ぜつつ運動習慣になりつつある&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;色彩検定2級を取る&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;できなかったこと、努力が足りなかったのは次の2点。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Kovaak  …. ゲーム自体のプレイ時間が少なくなったため中止&lt;/li&gt;
  &lt;li&gt;プログラミング … 趣味時間ではあまり集中してできていない&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2024年買って良かった物&quot;&gt;2024年買って良かった物&lt;/h2&gt;

&lt;p&gt;必要にかられて買った物はいくつかあるが、特に良かったと感じたのは以下の製品。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HITACHI &lt;a href=&quot;https://kadenfan.hitachi.co.jp/clean/lineup/pv-bh900sm/&quot;&gt;パワーブーストサイクロン&lt;/a&gt;　コードレススティック型掃除機
    &lt;ul&gt;
      &lt;li&gt;吸引力が強いのは正義かな、と思った&lt;/li&gt;
      &lt;li&gt;オプションパーツのホースなどにもLEDが付いてたりして、かゆいところに手が届く&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;イヤホンSeeAudio Yume Ultra
    &lt;ul&gt;
      &lt;li&gt;オーディオ用イヤホンのリプレースとして。AliExpressで初めて買った製品&lt;/li&gt;
      &lt;li&gt;今年前半はイヤホン沼に入門していた。すぐ抜け出した&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2024年ベスト書籍&quot;&gt;2024年ベスト書籍&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;夏目漱石『こころ』
    &lt;ul&gt;
      &lt;li&gt;ふと読み直したくなり&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;『ありす、宇宙までも』
    &lt;ul&gt;
      &lt;li&gt;この漫画が凄い（個人的に）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;藤井太洋『マン・カインド』&lt;/li&gt;
  &lt;li&gt;『ヴィクトリア朝時代のインターネット』
    &lt;ul&gt;
      &lt;li&gt;電信にまつわる歴史と物語かな、ノンフィクション&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;読み途中だけど『2030半導体の地政学』と『AI覇権　4つの戦場』もなかなか良い気がする。&lt;/p&gt;

&lt;h2 id=&quot;2025年やりたいこと&quot;&gt;2025年やりたいこと&lt;/h2&gt;

&lt;p&gt;目標に加えて、&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;新PC調達、Ryzen 9900Xかなぁ。今時点でGPUは新製品待ちの状態&lt;/li&gt;
  &lt;li&gt;引き続き言語処理系関連とRustでの実装&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;に挑戦していきたい。&lt;/p&gt;
</description>
        <pubDate>Tue, 31 Dec 2024 16:30:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2024/12/31/this-year-next-year.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2024/12/31/this-year-next-year.html</guid>
        
        
      </item>
    
      <item>
        <title>色彩検定3級を受験してきた</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/p/20241220_aft_card.jpg&quot; alt=&quot;色彩検定&quot; /&gt;&lt;/p&gt;

&lt;p&gt;先日、&lt;a href=&quot;https://www.aft.or.jp/&quot;&gt;色彩検定&lt;/a&gt;を受験し、3級に合格した。&lt;/p&gt;

&lt;h2 id=&quot;きっかけ&quot;&gt;きっかけ&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;よく行くアパレルショップの店員さんが「ぼくカラーコーディネートの資格持ってるんですよ」と言っていて興味を持った（3年以上前）&lt;/li&gt;
  &lt;li&gt;池袋ジュンク堂に行ったとき、偶然「色彩検定」の公式テキストを見つけた（1年以上前）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ちなみに業務には直接関係ないため、合否は特に業務範囲等に影響しない（けど役立つ可能性はあり）。&lt;/p&gt;

&lt;h2 id=&quot;受験と対策&quot;&gt;受験と対策&lt;/h2&gt;

&lt;p&gt;2, 3級はマークシートで、1級は二次試験で筆記があるらしい。
マークシートに備えて久しぶりにシャーペン（マークシート用）を購入した。&lt;/p&gt;

&lt;p&gt;公式テキストに加えて参考書を2冊購入してのぞんだ。&lt;/p&gt;

&lt;p&gt;過去問をやって難易度はわかっていたが、3級だと2週間程度（平日は仕事あり）の暗記でなんとかなった（個人差があります）。&lt;/p&gt;

&lt;h2 id=&quot;その他&quot;&gt;その他&lt;/h2&gt;

&lt;p&gt;家族に報告したら業務に関係なく姉も合格していることが発覚（しかも2級）。
意外と狭い世界なのかもしれない。&lt;/p&gt;

&lt;h2 id=&quot;将来&quot;&gt;将来&lt;/h2&gt;

&lt;p&gt;2級までは取得してもいいかもしれない。
また、せっかく勉強しているので写真撮影やウェブデザインなどにスキルを活かしたいところである。&lt;/p&gt;
</description>
        <pubDate>Fri, 20 Dec 2024 23:30:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2024/12/20/color.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2024/12/20/color.html</guid>
        
        
      </item>
    
      <item>
        <title>プラモデルのホワイト・グリントを製作した</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/p/IMGP0877_DxO.jpg&quot; alt=&quot;White Glint 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;ARMORED CORE for Answerというゲームに登場するロボット（機体）であるホワイト・グリントの&lt;a href=&quot;https://www.kotobukiya.co.jp/product/detail/p4934054056934/&quot;&gt;プラモデル（コトブキヤ）&lt;/a&gt;を製作した。ゲーム自体は2010年頃（訂正）にPS3でプレイしていたが、プラモデルは2014/06/07に購入してそこから製作を始めた。途中何度も組み立てる気力を失っていたが、今年に入りようやくホワイト・グリントが完成した。&lt;/p&gt;

&lt;p&gt;パーツとパーツの合わせ目が粗かったりすることもあるが、遠くから見る・撮影する分にはそれなりに見える。&lt;/p&gt;

&lt;p&gt;感想としては長かった。プラモデル作りは予想以上に工程があり、明示されてもいないので大変だった。
世のプラモデル好きな人はよくやるな、と思った。まぁ自分自身もそれに含まれてしまうのだけれど。&lt;/p&gt;

&lt;p&gt;次何か作る時はもうちょっと丁寧に作りたい。
せっかく製作したので、一応ブログに書いて供養しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/p/IMGP0880_DxO.jpg&quot; alt=&quot;White Glint 2&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 18 Apr 2024 20:30:00 +0900</pubDate>
        <link>https://blog.obfuscatism.net/2024/04/18/white-glint.html</link>
        <guid isPermaLink="true">https://blog.obfuscatism.net/2024/04/18/white-glint.html</guid>
        
        
      </item>
    
  </channel>
</rss>
