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
Yosuke Furukawa
PRO
July 25, 2026
Programming
320
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
250
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
520
Module Harmony について
yosuke_furukawa
PRO
4
1.9k
LTのやり方
yosuke_furukawa
PRO
16
3k
Other Decks in Programming
See All in Programming
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
680
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
550
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
500
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
230
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
170
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
260
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
500
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
140
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
550
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
490
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
680
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
170
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
640
Believing is Seeing
oripsolob
1
190
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
890
A better future with KSS
kneath
240
18k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
260
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
240
WENDY [Excerpt]
tessaabrams
11
39k
Paper Plane
katiecoart
PRO
2
53k
The SEO Collaboration Effect
kristinabergwall1
1
520
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Into the Great Unknown - MozCon
thekraken
41
2.7k
Side Projects
sachag
455
43k
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は僕の技術が好きという気持ちを体現した僕だけが得するプロダクト • でもそれでいいんじゃないか?難しく考えてほしくない • 「技術を知らなくてもプロダクトが作れる時代に僕は技術を知りたい」