Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
PHPのOpcodeを 読んでみよう
Search
yasuaki640
October 08, 2023
Programming
2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPのOpcodeを 読んでみよう
yasuaki640
October 08, 2023
More Decks by yasuaki640
See All by yasuaki640
LeetCode x AIで始める コーディング面接対策
yasuaki640
0
100
PHPのFFIを使って簡単なメロディを演奏する
yasuaki640
0
930
TypeScriptで簡易DBを作ってみた
yasuaki640
1
340
Other Decks in Programming
See All in Programming
すこし踏み込む CancellationToken
htkym
2
1.6k
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
910
AWSに止められる覚悟してますか?
morizo_1984
2
510
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
150
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
130
残高管理から台帳サービスへの進化
artoy
0
140
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Heart of Swift Concurrency
koher
0
1.2k
Jetpack Compose Mechanisms
skydoves
2
370
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
620
Verilogで学ぶCPU自作入門.pdf
uyuki234
8
4k
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
120
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
530
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
HDC tutorial
michielstock
2
940
BBQ
matthewcrist
89
10k
Amusing Abliteration
ianozsvald
1
330
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.2k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
970
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.1k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
710
Transcript
PHPのOpcodeを 読んでみよう ディップ株式会社 クライアントエンハンス課 渡邉泰曉 @yasuaki640
この発表のねらい 1. Opcodeを読む準備ができる 2. PHP処理系内部を垣間見、処理系に興味を持てる
Opcodeとは?(wikipediaより抜粋) (機械語に限らず)操作に関する命令のコード。 (中略) アセンブリ言語や仮想機械などの用語として用 いられる。 https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%9A%E3%82%B3%E3%83%BC%E3%83%89
Opcodeとは?(PHPでのダンプ形式) ADD CV0($a) CV1($b) オペコード オペランド(引数)
Opcodeの扱われ方(概要) 1. PHPコードを解析し、AST(抽象構文木)を出力 2. ASTからOpcodeを生成 3. OpcodeをPHP VMが実行 <?php echo
"Hello"; ECHO string("Hello") RETURN int(1) array( 0: Stmt_Echo( exprs: array( 0: Scalar_String( value: Hello ) ... 解析 生成(emit) VMに渡され実行
Opcodeの扱われ方(OPcache使用時) - Opcodeが共有メモリにキャッシュされる - PHPコードの解析~ASTの生成を飛ばすため処理が速い!! <?php echo "Hello"; ECHO string("Hello")
RETURN int(1) array( 0: Stmt_Echo( exprs: array( 0: Scalar_String( value: Hello ) ... 解析 生成(emit) VMに渡され実行 ここだけ実行
Opcodeを読むメリット(個人の感想です) - (手っ取り早く)PHP処理系の挙動を垣間見れる - php-srcリーディングの取っ掛かりとしやすい
Opcodeダンプの設定 - PHP 7.1以降であれば拡張を入れず、簡単に Opcodeダンプを出力できる - 詳細はAppendixに記載
Opcodeを読む <?php $a = 1; $b = 2; $c =
$a + $b; echo $c;
Opcodeを読む <?php $a = 1; $b = 2; $c =
$a + $b; echo $c; $_main: ; (lines=6, args=0, vars=3, tmps=4) ; (before optimizer) ; /workspace/experimental.php:1-6 ; return [] RANGE[0..0] 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002 T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1)
Opcodeを読む $_main: ; (lines=6, args=0, vars=3, tmps=4) ; (before optimizer)
; /workspace/experimental.php:1-6 ; return [] RANGE[0..0] 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002 T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) 実行時のメタ情報 ダンプされた Opcode
Opcodeを読む - PHP公式に各Opcodeの説明が記載 http://php.adamharvey.name/manual/ja/internals2.opcodes.php
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) PHPスクリプト上の 実際の変数($a, $b) に値を代入
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) 加算を実行し、 VM上の一時変数(T5)に 値を代入
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) VM上の一時変数(T5)の値を PHPスクリプト上の 実際の変数($c)に代入
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) 加算結果が代入された 変数に対しechoを実行
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) PHP側で 暗黙的に付与されるreturn ※詳細は略
Opcodeのハンドラを読む - マニュアルに説明がないOpcodeもある - php-srcに、Opcodeのハンドラ(処理の実体)を探して 読む - 今回はハンドラの探し方まで紹介
Opcodeのハンドラを読む <?php function welcome(string $target): string { $hi = 'Welcome
to' . $target; return $hi; } echo welcome('PHP conference!'); $_main: (省略) 0000 INIT_FCALL 1 144 string("welcome") 0001 SEND_VAL string("PHP conference!") 1 0002 V0 = DO_UCALL 0003 ECHO V0 0004 RETURN int(1) welcome: (省略) 0000 CV0($target) = RECV 1 0001 T2 = CONCAT string("Welcome to") CV0($target) 0002 ASSIGN CV1($hi) T2 0003 VERIFY_RETURN_TYPE CV1($hi) 0004 RETURN CV1($hi) 0005 VERIFY_RETURN_TYPE 0006 RETURN null
Opcodeのハンドラを読む welcome: (省略) 0000 CV0($target) = RECV 1 0001 T2
= CONCAT string("Welcome to") CV0($target) 0002 ASSIGN CV1($hi) T2 0003 VERIFY_RETURN_TYPE CV1($hi) 0004 RETURN CV1($hi) 0005 VERIFY_RETURN_TYPE 0006 RETURN null 引数の型チェック?? (ドキュメントに説明がない)
Opcodeのハンドラを読む - php-srcのzend_vm_execute.hに実際の処理が書 かれている ZEND_{Opcode名}_SPEC_{オペランドの種別}_HANDLER
Opcodeのハンドラを読む static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER (ZEND_OPCODE_HANDLER_ARGS) { オペコード名 オペランドの種別
Opcodeのハンドラを読む - ソースを読むだけではわからないことも多い - 本当にそのハンドラが呼ばれているのか? - デバッガを使う - 手順はネット上に豊富なため割愛
Opcodeのハンドラを読む
まとめ - PHPコードは内部でOpcodeにコンパイルされる - Opcodeを読むことは、php-srcリーディングなど深淵 の入り口におすすめ - パフォーマンスのため、OPcacheはちゃんと設定しよ う
採用やってます!!! - QRコードを読み取り、カジュアル面談しましょう!!
Appendix
参考にさせていただいた記事 - php-srcを読んでみよう - https://fortee.jp/phpcon-2022/proposal/1addf51d-6f72-4c96-9337-034ec6cc0643 - PHP による hello world
入門 - https://tech.respect-pal.jp/php-helloworld - PHP 7 Virtual Machine - https://www.npopov.com/2017/04/14/PHP-7-Virtual-machine.html - How to dump and inspect PHP OPCodes - https://php.watch/articles/php-dump-opcodes - Static Optimization of PHP bytecode (PHPSC 2017) - https://www.slideshare.net/nikita_ppv/static-optimization-of-php-bytecode-phpsc-2017 - Zend Engine 2 オペコード (PHP公式マニュアル) - http://php.adamharvey.name/manual/ja/internals2.opcodes.php - OPcache (PHP公式マニュアル) - https://www.php.net/manual/en/book.opcache.php - Implementing a Range Operator into PHP - https://phpinternals.net/articles/implementing_a_range_operator_into_php - Using CLion with php-src - https://dev.to/ramsey/using-clion-with-php-src-4me0
Opcodeダンプの設定 - .iniファイルでOPcacheの設定を有効にする - 今回はCLI版での実行を想定 zend_extension=opcache opcache.enable_cli=1
Opcodeダンプの設定 - スクリプト実行時にOpcodeダンプ出力のオプションを 渡す php -d opcache.opt_debug_level=0x10000 sample.php