**基本的なジャスト・イン・タイム コンパイラ(2015)**

2026/01/03 10:18

**基本的なジャスト・イン・タイム コンパイラ(2015)**

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

## 要約

この記事は、シンプルな再帰関係式を評価するための Hacker News /r/dailyprogrammer チャレンジに対して、小さな x86‑64 JIT コンパイラを構築する方法を示しています。解法では、各演算子(`+2`、`*3`、`-5`、`/7`)を実行時に機械語へコンパイルします。

## 実装手順

1. **メモリ割り当て**  
   * `mmap()`(Unix)または `VirtualAlloc()`(Windows)で書き込み可能なページを確保。  
   * 4096 バイトのバッファ(`PAGE_SIZE`)と次に空いているバイトを追跡するカウンタを持つ `asmbuf` 構造体を使用。

2. **命令発行**  
   * ヘルパー関数 `asmbuf_ins()` と `asmbuf_immediate()` が生のオペコードバイトと即値を書き込み。  
   * 例として使われるオペコード:  
     * 恒等変換 – `mov rax, rdi` (`0x48 89 f8`) + `ret` (`0xc3`).  
     * 加算 – `add rax, rdi` (`0x48 01 f8`).  
     * 減算 – `sub rax, rdi` (`0x48 29 f8`).  
     * 乗算 – `imul rax, rdi` (`0x48 0f af c7`).  
     * 除算 – RDX をゼロ拡張するために `xor rdx, rdx` (`0x48 31 d2`) と `idiv rdi` (`0x48 f7 f8`)。

3. **実行可能化**  
   * ページ保護を実行可能に変更:Unix では `mprotect()`、Windows では `VirtualProtect()` を使用。

4. **JIT 生成関数の呼び出し**  
   * バッファポインタを型 `long (*recurrence)(long)` の関数ポインタへキャストし、現在の項値で呼び出す。

## 呼び出し規約

* System V AMD64:引数は `rdi` に渡され、結果は `rax` で返却。  
* Windows:最初の引数は `rcx` に渡される。

JIT は直線コードのみを生成します;分岐やスタック使用がないため、線形再帰列にしか対応できません。

## 今後の作業

著者はさらに演算子(剰余、XOR、ビットシフト)と浮動小数点演算を追加する予定です。軽量アプローチは、LLVM などの重いフレームワークよりも速度や単純さで優れる場合に有用です。例としては、組込みシステム、ゲームスクリプティング、科学計算が挙げられます。

本文

2015年3月19日 – nullprogram.com/blog/2015/03/19/

(著者は現在米国での雇用機会を探しています。)
この記事は Hacker News と Reddit で議論されました。


課題

/r/dailyprogrammer の週次課題では、再帰関係式を読み取り、それを解釈し、指定された項数だけ繰り返すプログラムを書きます。

  • 初期値
    u(0)
    と操作列
    f
    が与えられます。
  • 各操作は前の項を更新します:
    u(n+1) = f(u(n))
  • 操作は 加算、減算、乗算、除算 のみで、それぞれ一つのオペランドがあります。

例:

u(n + 1) = (u(n) + 2) * 3 - 5

+2 *3 -5
と入力します。
u(0)=0
のとき、列は次のようになります:

nu(n)
00
11
24
313
440
5121

各操作を一つずつステップ実行するインタプリタを書く代わりに、著者は 簡易 x86‑64 Just‑In‑Time (JIT) コンパイラ を作成しました。
この JIT は操作列をネイティブ機械語へ変換し、CPU が直接実行できるようにします。

その後の課題では逆ポーランド記法(RPN)を採用してより複雑な式が扱えるようにし、その提出には別の JIT が書かれました。


実行可能メモリの確保

現代OSは ページ単位での保護 を課します:読み取り、書き込み、実行の権限。
典型的なコードページは read+execute ですが書けません;データページは read+write で実行不可です。

これによりシェルコードなどの攻撃を防ぎ、不正アクセスはセグメンテーションフォールトで即座に検出されます。

命令バッファ

malloc()
は書き込み可能だが実行不可のメモリを返します。
したがって JIT では
mmap()
(Windows なら
VirtualAlloc()
)を使い、ページ境界に揃ったバッファを取得します。

#define PAGE_SIZE 4096

struct asmbuf {
    uint8_t code[PAGE_SIZE - sizeof(uint64_t)];
    uint64_t count;
};

struct asmbuf *asmbuf_create(void) {
    int prot = PROT_READ | PROT_WRITE;
    int flags = MAP_ANONYMOUS | MAP_PRIVATE;
    return mmap(NULL, PAGE_SIZE, prot, flags, -1, 0);
}

Windows 版:

struct asmbuf *asmbuf_create(void) {
    DWORD type = MEM_RESERVE | MEM_COMMIT;
    return VirtualAlloc(NULL, PAGE_SIZE, type, PAGE_READWRITE);
}

コード生成後に

mprotect()
(または
VirtualProtect()
)で実行権限を付与し、終了時には
munmap()
VirtualFree()
)で解放します。


命令の挿入

生の機械語をバッファへ書き込むヘルパー関数が二つあります:

asmbuf_ins(struct asmbuf *, int size, uint64_t ins);
asmbuf_immediate(struct asmbuf *, int size, const void *value);

例:

恒等関数(

mov rax,rdi
ret
)を生成する場合:

asmbuf_ins(buf, 3, 0x4889f8);   // mov rax,rdi
asmbuf_ins(buf, 1, 0xc3);       // ret

オペランドは

asmbuf_immediate()
で埋め込みます。


呼び出し規約

生成される関数は System V AMD64 ABI を使用します:

  • 最初の整数引数 →
    rdi
  • 戻り値 →
    rax

Windows では最初の引数が

rcx
に渡りますが、それ以外は同じアセンブリです。


操作の生成

各演算子に対応する命令列を組み立てます。
例:

switch (operator) {
    case '+':
        asmbuf_ins(buf, 3, 0x4801f8);   // add rax,rdi
        break;
    case '-':
        asmbuf_ins(buf, 3, 0x4829f8);   // sub rax,rdi
        break;
    case '*':
        asmbuf_ins(buf, 4, 0x480fafc7); // imul rax,rdi
        break;
    case '/':
        asmbuf_ins(buf, 3, 0x4831d2);   // xor rdx,rdx
        asmbuf_ins(buf, 3, 0x48f7ff);   // idiv rdi
        break;
}

Tip:

%
(剰余)、
^
(XOR)、ビットシフト
<<
,
>>
を追加したり、浮動小数点演算に切り替えることも可能です。


生成コードの実行

バッファを確定させた後:

asmbuf_finalize(buf);
long (*recurrence)(long) = (void *)buf->code;

これで通常の C 関数として呼び出せます:

x[n + 1] = recurrence(x[n]);

要約

  • JIT は単純な算術再帰関係式をネイティブ x86‑64 コードへコンパイルします。
  • メモリ保護は安全に扱い、呼び出し規約を尊守し、生成コードを最小オーバーヘッドで実行します。
  • この手法は特定の問題にはシンプルかつ有効ですが、より複雑なケースでは LLVM などフルスケールのコンパイラフレームワークを検討すべきです。

同じ日のほかのニュース

一覧に戻る →

2026/01/03 4:48

自分のサイトで公開し、他所ではシンジケート(転載)してください。

## Japanese Translation: --- ## 要約 POSSE(**Publish on Your Own Site, Syndicate Elsewhere**)は、作家がまず自分のサイトにコンテンツを投稿し、その後第三者のサイロへ複製することで、元のコピーを完全に管理したまま公開できる出版モデルです。主なメリットは、外部プラットフォームへの依存度低減、正規URLの所有権確保、検索性向上、シンジケートからのレスポンスを逆流させる能力、およびソーシャルレイヤーの活用です。すべて自己ホスト状態を犠牲にすることなく実現します。 POSSEは、パーマショートリンクや引用経由でシンジケートコピーからのバックリンクを奨励し、発見性を高め、スパム対策を行い、元記事のSEOを向上させます。モデルは完全なCRUD操作をサポートします:下流コピーをu‑syndicationリンクで読み取り、編集または再投稿で更新し、既存アクティビティを考慮して削除できます。 ### 実装パターン 1. **自動サーバー側シンジケーション**(クライアント → サイト → サイロ):新しいコンテンツが公開されると、サイトは自動的にサイロへ投稿します。 2. **クライアント → サイト + 手動サイロ投稿**:クライアントがローカルで公開し、その後選択したサイロへ手動で投稿します。この方法はより多くの制御を提供しますが、自動化は減少します。 ### 人気のあるサイロ Twitter、Facebook、Medium、WordPress.com、Flickr、Mastodon、Bluesky など。 ### POSSEを可能にするツール Bridgy Publish、SiloRider、Feed2Toot、POSSE Party などが挙げられます。 ### 関連概念 - **COPE**(Create Once, Publish Everywhere) - **POSE**(Publish Once Syndicate Everywhere) - **PESOS**(Post Elsewhere, Syndicate to Own Site) - **PESETAS**(post to a single silo only) ### 歴史的マイルストーン Tantek Çelik が 2010 年に POSSE を定義し、2012 年に正式化しました。それ以来、Barnaby Walters、Aaron Parecki、Ben Werdmuller、Shane Becker、および Molly White といった IndieWeb 実践者がさまざまな CMS やカスタムセットアップで導入しています。エコシステムは 2024 年までに新しいツールとデプロイメントを通じて着実に成長しました。 ### 今後の展望 本文では、POSSE ユーティリティの継続的な拡張と多様な「サイロ」への広範な採用が予測されています。さらに非ウェブ領域(例:git リポジトリのミラーリング)まで拡大する可能性があります。このシフトは、個人クリエイターや小規模ビジネスに力を与え、支配的プラットフォームへの依存を減らしつつ SEO とオーディエンス エンゲージメントを向上させることが期待されます。

2026/01/03 13:01

**IQuest‑Coder:Claude Sonnet 4.5 および GPT 5.1 を凌駕する新しいオープンソースコードモデル**

## Japanese Translation: --- ### Summary GitHubは、Copilotとその拡張AIツールキット(Spark、Models、MCP Registry)でコードを書き、Actions、Codespaces、Issues、Code Review、および自動ワークフローパイプラインを通じてアプリケーションのデプロイ、監視、セキュリティを行うという、ソフトウェア開発のすべての段階をスムーズにする完全統合型AI搭載開発者プラットフォームとして自社を位置付けています。 このプラットフォームは、GitHub Advanced Security の脆弱性スキャンとシークレット保護という高度なセキュリティ機能を、CI/CD ライフサイクル全体にわたるオートメーションツールと統合しています。ターゲットユーザーは、企業、中小規模チーム、スタートアップ、非営利団体、およびアプリモダニゼーション、DevSecOps、DevOps、継続的インテグレーション/デプロイメントなどの専門ユースケースを含む広範なスペクトルです。 明示的に対応する産業にはヘルスケア、金融サービス、製造業、および政府があり、それぞれのセクター向けにカスタマイズされたソリューションが提供されています。 GitHub の戦略は、プロンプト管理やインテリジェントなアプリデプロイメントなどAI統合を深化させるとともに、エンタープライズグレードのセキュリティ機能、Copilot for Business、プレミアム24/7サポート、および追加オプションの拡充を図っています。これらの動きはコーディングワークフローの高速化、コンプライアンス制御の強化、およびプラットフォーム全体の魅力拡大を目指しています。 コミュニティエンゲージメントは、Security Lab、Maintainer Community、Accelerator、Archive Program、GitHub Sponsors プログラムなどのイニシアチブを通じて強化され、オープンソース開発者を支援し、ソフトウェア業界全体での協力を促進します。ドキュメント、ブログ、変更履歴、マーケットプレイス、コミュニティフォーラム、およびパートナープログラムは、ユーザーが開発ジャーニーを通じて継続的にサポートされるようにさらに支援しています。 ---

2026/01/03 6:27

「『Harder, Better, Faster, Stronger』のBPMに合わせたダフトパンクのイースターエッグはありますか?」

## Japanese Translation: ## 改訂要約 Daft Punk の「Harder, Better, Faster, Stronger」は一般的に 123 BPM としてリストされていますが、正確な分析では実際のテンポは **123.45 BPM** であることが示されました。この微妙さは標準の一覧では見落とされがちです。 著者はリアルタイム BPM 検出アプリ「Tempi」を構築し、数百曲のサニペットライブラリでテストしました。Tempo アプリを使って手動でテンポを測定し、最初の明確なビート(約 5.58 秒)と最後のビート(約 3:41.85 秒)の間にある全ビート数をカウントし、式 `bpm = 60 * (number_of_beats‑1) / duration` を適用しました。Discovery CD のリップでは **123.44994 BPM** が得られ、YouTube バージョンでは **123.45336 BPM** でした。両方とも四捨五入すると **123.45 BPM** に一致します。CD バージョンは処理が少ないため、より代表的と考えられます。 著者は FFT(高速フーリエ変換)や自己相関に依存するアルゴリズムベースのテンポ検出ツールはノイズが多く不正確である可能性を指摘し、手動測定の方がより信頼できる数値を提供すると述べています。 Daft Punk の機材—E‑mu SP‑1200、Akai MPC‑3000、および Emagic Logic—は BPM を異なる小数点精度でサポートしています(前二つでは一桁、Logic では最大四桁)。2001 年と 2013 年のインタビューでは、これらのデバイスでシーケンスを行い、コンピュータを使わないという主張があり、制作時に分数 BPM が可能だったことを示唆しています。 結論として、正確な **123.45 BPM** は Daft Punk の「ロボット的」プロダクションプロセスによる意図的なイースターエッグであると考えられます。このような隠された詳細を認識することは、音楽テック開発者、DJ、および作品に微妙な参照を埋め込むアーティストに有益です。