Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
jsmini JavaScript Engine を作ってみた話
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Yosuke Furukawa
PRO
July 25, 2026
Programming
350
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
jsmini JavaScript Engine を作ってみた話
Qiita Tech Festa 2026 で発表
Yosuke Furukawa
PRO
July 25, 2026
More Decks by Yosuke Furukawa
See All by Yosuke Furukawa
デザインシステムが必須の時代に
yosuke_furukawa
PRO
2
260
Node.js, Deno, Bun 最新動向とその所感について
yosuke_furukawa
PRO
10
5.3k
Welcome JSConf.jp 2024
yosuke_furukawa
PRO
1
4.8k
tc39 x jsconf.jp Panel Discussion 2024
yosuke_furukawa
PRO
0
360
Removing Corepack
yosuke_furukawa
PRO
9
2k
JavaScript Runtime とはなにか
yosuke_furukawa
PRO
15
3.2k
Strip Types と Storage
yosuke_furukawa
PRO
4
530
Module Harmony について
yosuke_furukawa
PRO
4
2k
LTのやり方
yosuke_furukawa
PRO
16
3.1k
Other Decks in Programming
See All in Programming
高専キャリア LT 発表内容
crysta1221
6
5.3k
Introducing Stack Pull Request in GitHub
kkamegawa
0
120
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
600
AIエージェント時代のコードレビューを設計する
nogu66
3
760
異なる設計思想のフレームワークを経験して得た学び
amekuhideki
2
1.4k
自分的「カンファレンスの楽しみ方」
syumai
0
160
Go 1.27 における memory allocation の高速化
andpad
0
360
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
170
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.8k
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
120
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
8k
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.5k
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
Leo the Paperboy
mayatellez
8
2.2k
Become a Pro
speakerdeck
PRO
31
6.2k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
590
A Soul's Torment
seathinner
7
3.5k
Statistics for Hackers
jakevdp
799
230k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
320
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
490
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Transcript
JavaScript Engine を作った話 (AIといっしょに) Qiita Tech Conference 2026 古川陽介 /
2026/07/25
X: @yosuke_furukawa GitHub: yosuke-furukawa
AI と学ぶ
AI時代において、タスクはAIにおまかせしてて もできてしまう時代である
やれ Loop Engineering だとか、 Claude Fable だとか、この skill 使うといいよとか (ちょっと飽きちゃった)
AI時代だからこそ「AIを業務に使う」だけじゃなくて そもそも知りたかった好奇心を満たすツールにしよう
というわけで本題
JS Engine を作ってみた話
JS Engine • JavaScript のエンジン • JavaScript は 「エンジン」 と「ランタイム」に分かれて実行するモデル
• ランタイム = ブラウザ、Node.js、Deno、Bun • エンジン = V8, JavaScriptCore, SpiderMonkey
JS Runtime • よく聞かれるエンジンとランタイムの違い • エンジンは言語を使った「計算」を担当 JavaScript 機能群 • ランタイムは環境ごとの差異を吸収し、
JavaScript Runtime 環境ごとに必要なAPIを提供する • 例: ブラウザで言うと DOM Node.jsは HTTP Server など DOM, fetch/XHR, navigator, EventLoop JavaScript Engine 分岐処理、繰り返し処理、Promise, 構文
JS Engine motivation • 僕はこれまで Node.js やブラウザを専門としてきた • いわゆる「ランタイム」側の専門家であった。 •
JavaScript 「エンジン」 のことはもちろん知ってた。 • でも内容が難しい、中身を理解しようにも概要レベル以上のものを理解するのは困難 だった。 • AI がせっかくあるなら作ってみようと思った。 • 作りながらわからないことを聞きながら作れば、ゼロから自分で作るのは難しくて も、非常に学びになるはずだと思った。
JS Engine • ざっくり大きく分けて 4 ステップに分かれてる 1. Tokenize 字句解析 2.
Parse 構文解析 3. Bytecode Generate バイトコード生成 4. JIT Compile JIT コンパイル Tokenize Parse Bytecode Generate JIT Compile
Tokenize 字句解析 • めっちゃざっくり言うと、スクリプトという文書を単語に分割する処理 Function Identi ier LeftParen Identi ier
Identi ier RightParen LeftBrace f f f Tokenize Parse Bytecode Generate JIT Compile
Tokenize 字句解析 • 単語に分割したうえで、それが何を表すのかを粗く解析する • 数字なのか?文字なのか?記号なのか? • 文字だとしたらそれは予約されてるキーワードなのか? • 記号だとしたらどんな記号なのか?
• パターンマッチの要領で機械的に解析する Tokenize Parse Bytecode Generate JIT Compile
Tokenize 字句解析 • 最終的に単語とその種別をまとめた結果が出てくる Tokenize Parse Bytecode Generate JIT Compile
Tokenize 字句解析 • ちなみに V8 は・・・ • tokenize 1つとっても特徴的 •
一つ一つのtoken解析の際に非同期に処理できるようになってる • JavaScript の特性上、HTTPからファイルを受け取りながら解析するという目的のためにそう なってる • 普通プログラミング言語は全部のスクリプトが揃ってることが前提なのでこんなふうになっ てるのは JavaScript 特有。マジで変態。 Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • これもめっちゃざっくり言うと、トークンの種別をベースにそれぞれの関係 性を作る。もっと言えばトークンの種別の解析結果を元に木構造にする Function Identi ier LeftParen Identi
ier Identi ier RightParen LeftBrace f f f Tokenize Function Declaration Parse Bytecode Generate Block Statement Return Statement Binary Expression JIT Compile
Parse 構文解析 • 木構造にする Function Declaration Block Statement Return Statement
Binary Expression Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • 木構造は専門的に言うと Abstract Syntax Tree 抽象構文木となる。 • 抽象構文木にする理由はコンピュータで辿りやすいから
• 辿ることで処理が実行できるようになる • これを実行以外の用途で活かしたものが Linter (プログラムのバグチェック) であったり Mini ier (プログラムの不要な処理の削減及び変数の短縮化)であっ たりする f Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • AST(木構造)を辿るだけで実行する形式もある、それをインタプリタと呼ぶ • インタプリタは左から順に辿り 演算内容があったら処理していく • ははーんなるほど、辿って処理 していくだけなら簡単そうだな
と思った人、甘いです。 Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • 辿って処理するだけって言っても、変数や関数の話が入ってくると少し複雑 Parse時だけでは値は決まらない 関数を実行する時になって はじめて a, b に値が入って
計算可能になる Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • 変数を解決するための箱(Environment)を用意しないといけない Tokenize Parse Bytecode Generate key value
a 1 b 1 JIT Compile
Parse 構文解析 • 変数を解決するための箱(Environment)を用意しないといけない • さらに言うと、その箱は特定の関数の中からしか使えないようにしないとい けない(スコープ) • またさらに言うと自分の外側のスコープにある変数も使えないといけない (スコープは入れ子になる)
Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • つまり、JavaScriptの以前までの仕様で関数スコープとグローバルスコープだ けだったとしても、関数を作るたびにスコープと変数を入れる箱が必要にな る • 現代のJavaScriptはこれに加えてブロックスコープなどもあるのでより複雑 Tokenize Parse
Bytecode Generate JIT Compile
Parse 構文解析 • つまり、JavaScriptの以前までの仕様で関数スコープとグローバルスコープだ けだったとしても、関数を作るたびにスコープと変数を入れる箱が必要にな る • 現代のJavaScriptはこれに加えてブロックスコープなどもあるのでより複雑 インタプリタ式で解決する場合、木構造を辿りながら、関数呼び出しの たびに毎回箱を用意しつつ、変数を見つける際にも自分の箱の中だけ
Bytecode ではなく、上の箱にある変数も見つけに行かないといけない Tokenize Parse JIT Compile Generate
Parse 構文解析 • なのでインタプリタ式で実行するJavaScriptエンジンはほとんど存在しない • 木構造を辿りながら、スコープチェーンを辿りながらという方式だと速くな らない • 現代のJavaScriptエンジン(v8, JSC,
SpiderMonkey)はバイトコード生成、そ の後のJITコンパイルに繋げるアーキテクチャになってる Tokenize Parse Bytecode Generate JIT Compile
Parse 構文解析 • ちなみに v8 はここでも変態 • 構文解析を2回する • 最初にざっくり関数ブロックを見つけたらその中身まで追いに行かない
• こうすることで処理を分散させている、JavaScriptの解析に時間がかかりす ぎるとHTML,CSSの処理に影響出るのでそれを軽減するため • 変態、普通はそんな事しない Tokenize Parse Bytecode Generate JIT Compile
Bytecode Generate バイトコード生成 • バイトコード生成は木構造(AST)の構造を一回ざっくり読み、読んだ上で演算 するための命令の配列だけ生成する。 • 変数を格納する箱も別途配列で用意する。 • 木構造の操作をしながら実行するのではなく、木構造を一回全部スキャンし
て命令配列を生成し、その配列の操作だけで完結できるようにする。 • 考えた人は天才。 Tokenize Parse Bytecode Generate JIT Compile
Bytecode Generate バイトコード生成 • 木構造を一回辿ってバイトコードを生成する Tokenize Parse Bytecode Generate JIT
Compile
Bytecode Generate バイトコード生成 • バイトコードは何がいいのか? • 木構造を辿りながら、変数を管理しながら、計算するのは至難の業 • ドン・キホーテの店舗の中を買いたいものを考えながら歩いてなるべく短時 間で買おうとするくらい困難
• 一回ドン・キホーテの店舗の中を歩いて土地勘を掴み、買いたいものをリス トアップしたうえで最短距離を歩いたほうが早い Tokenize Parse Bytecode Generate JIT Compile
Bytecode Generate バイトコード生成 • バイトコードは何がいいのか? • それと同じで、木構造を一度命令の配列にする • そうするとあとは配列操作だけで実行できる Tokenize
Parse Bytecode Generate JIT Compile
Bytecode Generate バイトコード生成 • バイトコードバイトコードと言っているが、実際はエンジンの言語内にある 配列操作にすぎない。多くの場合は C++ の配列操作で、 C++ の演算を行う
• 今回作っている jsmini は中身は JavaScript なので JavaScript の配列操作で JavaScript の演算を行う Tokenize Parse Bytecode Generate JIT Compile
JIT Compile • とうとうここまできた。 • バイトコードで命令配列操作だったら高速 • でもそれはあくまで「木構造のスキャンしながら演算する」のに比べたら高 速という程度 •
「最速」ではない Tokenize Parse Bytecode Generate JIT Compile
JIT Compile • そもそも最速な処理とは? • 1 + 1 を考える。もちろん 2
である。 • でも計算機の世界では? • 数値1つとっても型がある。型同士で演算の仕方は違う。 同じ 1 + 1 でも整数の 1 + 1 と小数を含んだ 1.0 + 1.0 は処理方法が違う。 • もっと言えば 32bit 表現なのか64bit表現なのかでメモリに割り当てるサイズ も違う Tokenize Parse Bytecode Generate JIT Compile
JIT Compile • 最小メモリ割り当てサイズで最適な処理方法で演算できる必要がある • それには型を見つける必要がある • JavaScript の数値は仕様上、全て浮動小数点数表現になっているが、実際の 処理は整数がほとんどである
• どうやって型を見つける・・・? Tokenize Parse Bytecode Generate JIT Compile
JIT Compile • こたえ: 実行してみて見つける • 何回か実行しているうちにどうやらこの値って整数・・・? • みたいに推測する •
推測された値を元に計算を最適化する Tokenize Parse Bytecode Generate JIT Compile
JIT Compile • 関数やループ内の処理ブロックをきっかけに実行後の情報をためておく • 型のフィードバックを行う foo関数の引数も戻り値もuint32っぽい? Tokenize Parse Bytecode
Generate JIT Compile
JIT Compile • 繰り返し繰り返し処理が溜まっていくことで「推測の確度」が上がる • それをもとに最適化する int32であることを元に計算を最適化 Tokenize Parse Bytecode
Generate JIT Compile
JIT Compile • jsmini では バイトコードから WASM の命令に変換 • でも
v8 ではもちろんCPUの命令に変換(WASMよりもその方が速いので) • 中々個人では v8 に追いつくことは困難・・・(AIを持ってしても) Tokenize Parse Bytecode Generate JIT Compile
JIT Compile • 型の推定はJIT Compileの初歩機能である • 実際にはこの他にもエグい最適化をいっぱい行う • 定数畳み込み(const a
= 1 + 1 + 3; みたいになってたら a = 5 にしちゃう) • ループの不変部分の移行(forの中で変わらない値があれば外出しする) • デッドコード削除(使ってないコードをそもそも消す) Tokenize Parse Bytecode Generate JIT Compile
DEMO https://yosuke-furukawa.github.io/jsmini/ Tokenize Parse Bytecode Generate JIT Compile
まとめに入ります
JS Engine を作ってみた
作ってみたら、ものすごく面白かった。 分からなかったことが分かる喜び。
よく考えるとJavaScriptはすごく特殊、 仕様含めて破綻していないのがすごい。 AIとかで矛盾も指摘できない頃からやってる
AIをどう使ったか
AI使い方 • 5つのフェーズに分かれて使った • RESEARCH: 調査フェーズ、他実装の内容、論文調査など • PLAN: いわゆるPLANモード、実装計画の策定 •
TODO: より具体的な実装計画、 • Implement: 実装 • LEARN: 振り返りの実施 • 具体的なのは https://github.com/yosuke-furukawa/jsmini ここを。 RESEARCH PLAN TODO Implement LEARN
僕が伝えたいこと • AIをどう使ったか、今後どうなるかみたいな話をしたかったわけじゃない • 好奇心や探究心を持ってAIを使っていくことで自分の見識を深めてほしい • 見識が深くなることは AI ツールを使う上でももちろん重要だし、問題発見認識ができるよ うになる
• 技術が好きで技術を学びたいという気持ちを持ち続けてほしい • jsminiは僕の技術が好きという気持ちを体現した僕だけが得するプロダクト • でもそれでいいんじゃないか?難しく考えてほしくない • 「技術を知らなくてもプロダクトが作れる時代に僕は技術を知りたい」