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
100
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
240
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
350
Removing Corepack
yosuke_furukawa
PRO
9
2k
JavaScript Runtime とはなにか
yosuke_furukawa
PRO
15
3.1k
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
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
150
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
関数型プログラミングのメリットって何だろう?
wanko_it
0
190
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
140
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
120
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.7k
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.9k
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
120
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
340
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
1.7k
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
150
Featured
See All Featured
BBQ
matthewcrist
89
10k
It's Worth the Effort
3n
188
29k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Prompt Engineering for Job Search
mfonobong
0
380
Skip the Path - Find Your Career Trail
mkilby
1
170
A Modern Web Designer's Workflow
chriscoyier
698
190k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.7k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.6k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.9k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
72
40k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
220
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は僕の技術が好きという気持ちを体現した僕だけが得するプロダクト • でもそれでいいんじゃないか?難しく考えてほしくない • 「技術を知らなくてもプロダクトが作れる時代に僕は技術を知りたい」