Slide 1

Slide 1 text

polamjag / Satoru Abe 転ばぬ先のXS⼊⾨ 2025-11-15 #yapcjapan #yapcjapanC YAPC::Fukuoka 2025

Slide 2

Slide 2 text

突然ですが List::Util::min https://metacpan.org/pod/List::Util#min 2

Slide 3

Slide 3 text

突然ですが List::Util::min 3 https://github.com/Pe rl/perl5/blob/c7aed9f/ cpan/Scalar-List-Utils/ ListUtil.xs#L270-L319

Slide 4

Slide 4 text

突然ですが List::Util::min 4 https://github.com/Pe rl/perl5/blob/c7aed9f/ cpan/Scalar-List-Utils/ ListUtil.xs#L270-L319

Slide 5

Slide 5 text

% whoami - id:polamjag《ポラムジャグ》 - 株式会社はてな ノベルチーム - ex-ブログチーム、マンガメディアチーム - TypeScript, Perl, Go ほかいろいろ - 生まれも育ちも大分県 5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

緊急 アンケート 7

Slide 8

Slide 8 text

かつてPerlを 読み書きしていた 時期がある? 8 1

Slide 9

Slide 9 text

ここ1年以内に Perlを 読み書きした? 9 2

Slide 10

Slide 10 text

XSを読み書き したことがある? 10 3

Slide 11

Slide 11 text

Perlに限らずRuby, Python, Node.jsなども含めて ネイティブ拡張つき ライブラリのインストールで 苦労したことがある? 11 4

Slide 12

Slide 12 text

12

Slide 13

Slide 13 text

🍵 13

Slide 14

Slide 14 text

本セッションでは、普段Perlを読み書きしているがXSにはあ まり触れたことがない方を主な対象に、XSモジュールに対す る心理的なハードルを下げ、リファレンスなどを参照しなが ら既存のライブラリなどの実装を理解したり、トラブル シューティングができるようになることを目指します。ま た、Perlに馴染みがない方にとっても、スクリプト言語にお けるネイティブ拡張の仕組みのケーススタディとして楽しん でいただければと思います。 https://fortee.jp/yapc-fukuoka-2025/proposal/77fc7998-edaf-4e11-9dda-9f5e96cfe8b6 14

Slide 15

Slide 15 text

本セッションでは、普段Perlを読み書きしているがXSにはあ まり触れたことがない方を主な対象に、XSモジュールに対す る心理的なハードルを下げ、リファレンスなどを参照しなが ら既存のライブラリなどの実装を理解したり、トラブル シューティングができるようになることを目指します。ま た、Perlに馴染みがない方にとっても、スクリプト言語にお けるネイティブ拡張の仕組みのケーススタディとして楽しん でいただければと思います。 https://fortee.jp/yapc-fukuoka-2025/proposal/77fc7998-edaf-4e11-9dda-9f5e96cfe8b6 15

Slide 16

Slide 16 text

本セッションでは、普段Perlを読み書きしているがXSにはあ まり触れたことがない方を主な対象に、XSモジュールに対す る心理的なハードルを下げ、リファレンスなどを参照しなが ら既存のライブラリなどの実装を理解したり、トラブル シューティングができるようになることを目指します。ま た、Perlに馴染みがない方にとっても、スクリプト言語にお けるネイティブ拡張の仕組みのケーススタディとして楽しん でいただければと思います。 https://fortee.jp/yapc-fukuoka-2025/proposal/77fc7998-edaf-4e11-9dda-9f5e96cfe8b6 16

Slide 17

Slide 17 text

本セッションでは、普段Perlを読み書きしているがXSにはあ まり触れたことがない方を主な対象に、XSモジュールに対す る心理的なハードルを下げ、リファレンスなどを参照しな がら既存のライブラリなどの実装を理解したり、トラブル シューティングができるようになることを目 指します。ま た、Perlに馴染みがない方にとっても、スクリプト言語にお けるネイティブ拡張の仕組みのケーススタディとして楽しん でいただければと思います。 https://fortee.jp/yapc-fukuoka-2025/proposal/77fc7998-edaf-4e11-9dda-9f5e96cfe8b6 17

Slide 18

Slide 18 text

XSモジュールにまつわるトラブル (俺調べ) 18 ※冗談です

Slide 19

Slide 19 text

XSモジュールにまつわるトラブル (俺調べ) 19

Slide 20

Slide 20 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood - XS、「ネイティブ拡張」とは - XSモジュールインストール under the hood 20

Slide 21

Slide 21 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood - XS、「ネイティブ拡張」とは - XSモジュールインストール under the hood 21

Slide 22

Slide 22 text

CPANモジュールをインストールすると き - ビルドツール - Makefile.PL: ExtUtils::MakeMaker - perl Makefile.PL で Makefile が生成される - Build.PL: Module::Build, Module::Build::Tiny - perl Build.PL で Build というファイル名のシェルスク リプトが生成される - オーサリングツール - Minilla, Dist::Zilla, … 22

Slide 23

Slide 23 text

CPANモジュールをインストールすると き - App::cpm のインストール処理を覗いてみると… - fetch, configure, install の三段階 - そのうち configure で Makefile.PL や Build.PL を探して実行 - install で↑ で生成されたものを実行 - https://github.com/skaji/cpm/blob/74e217556acec88fe798 d4935efe7a9c50d19e28/lib/App/cpm/Worker/Installer.pm - static install (ビルドスクリプトの実行なしに、ファイルのコピーのみ のインストール) という概念もある - https://github.com/Perl-Toolchain-Gang/cpan-static 23

Slide 24

Slide 24 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood ✅ - XS、「ネイティブ拡張」とは - XSモジュールインストール under the hood 24

Slide 25

Slide 25 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood - XS、「ネイティブ拡張」とは - XSモジュールインストール under the hood 25

Slide 26

Slide 26 text

“XS” is 何 XSはPerlとCのコード (またはCライブラリ) との間の拡張インターフェースを 作るのに使われるインターフェース記述ファイルフォーマットです。 XSインターフェースはライブラリと動的または静的にリンクされて、Perl とリンクすることのできる新しいライブラリを生成します。 XSインターフェース記述はXS言語で書かれており、Perl拡張インター フェースのコアコンポーネントです。 — https://perldoc.jp/docs/perl/5.20.1/perlxs.pod (一部略・強調は引用者による) 26

Slide 27

Slide 27 text

“XS” is 何 XSはPerlとCのコード (またはCライブラリ) との間の拡張インターフェースを 作るのに使われるインターフェース記述ファイルフォーマット です。 XSインターフェースはライブラリと動的または静的にリンクされて、Perl とリンクすることのできる新しいライブラリを生成します。 XSインターフェース記述はXS言語で書かれており、Perl拡張インター フェースのコアコンポーネントです。 — https://perldoc.jp/docs/perl/5.20.1/perlxs.pod (一部略・強調は引用者による) 27

Slide 28

Slide 28 text

「XS」はプログラミング言語だった! - XS - xsubpp -> C - xsubpp - compiler to convert Perl XS code into C code - https://perldoc.perl.org/xsubpp - “This compiler is typically run by the makefiles created by ExtUtils::MakeMaker or by Module::Build or other Perl module build tools” - ExtUtils::ParseXSに実装がある - https://github.com/Perl/perl5/blob/blead/dist/ExtUtils-ParseXS/lib/ExtUtils /ParseXS.pm - 「大規模なリファクタリングが始まっている」!! - https://speakerdeck.com/charsbar/2025nian-qiu-noperl?slide=59 28

Slide 29

Slide 29 text

“XS” is 何 XSはPerlとCのコード (またはCライブラリ) との間の拡張インターフェースを 作るのに使われるインターフェース記述ファイルフォーマットです。 XSインターフェースはライブラリと動的または静的にリンクされて、 Perl とリンクすることのできる新しいライブラリを生成します 。 XSインターフェース記述はXS言語で書かれており、Perl拡張インター フェースのコアコンポーネントです。 — https://perldoc.jp/docs/perl/5.20.1/perlxs.pod (一部略・強調は引用者による) 29

Slide 30

Slide 30 text

Perlランタイム Perlプログラム (*.pl, *.pm) 自分が書いたコード CPANモジュール …… 世界観 30

Slide 31

Slide 31 text

Perlランタイム Perlプログラム (*.pl/*.pm) https://github.com/Perl/perl5 31

Slide 32

Slide 32 text

Your C code 共有ライブラリ (*.dll, *.so, *.dylib, …) 静的ライブラリ ビルド時に静的リンク ビルド時に動的リンク or 実行時に動的ロード 32

Slide 33

Slide 33 text

“XS” is 何 XSはPerlとCのコード (またはCライブラリ) との間の拡張インターフェースを 作るのに使われるインターフェース記述ファイルフォーマットです。 XSインターフェースはライブラリと動的または静的にリンクされて、 Perl とリンクすることのできる新しいライブラリを生成します 。 XSインターフェース記述はXS言語で書かれており、Perl拡張インター フェースのコアコンポーネントです。 — https://perldoc.jp/docs/perl/5.20.1/perlxs.pod (一部略・強調は引用者による) 再掲 33

Slide 34

Slide 34 text

Perl ランタイム 共有ライブラリ (*.dll, *.so, *.dylib, …) 静的ライブラリ ビルド時に静的リンク ビルド時に動的リンク or 実行時に動的ロード PerlのXSは静的リンクも可能 (!) だが、Webアプリケーションの開発という文脈においては 動的ロードを想定したXSライブラリの利用がほとんどであるはず…… 😮 34

Slide 35

Slide 35 text

(Web開発でよく出会う) XSモジュールの類型 - 特定処理の最適化 - /デ?シリアライズ/ (e.g. JSON::XS) - テンプレートエンジン (e.g. Text::Xslate) - ネイティブライブラリのラッパー - e.g. DBD::mysql (→ libmysqlclient) - 言語ランタイムの機能拡張的な側面 - e.g. AnyEvent (RubyでいうEventMachine的な存在[要出典]) 35

Slide 36

Slide 36 text

Perlランタイム Perlプログラム (*.pl, *.pm) 共有 ライブラリ (XS由来) 動的ロード 共有 ライブラリ (外部) 動的リンク 「ネイティブライブラリのラッパー」 の典型的なシーン PerlのXSは静的リンクも可能 (!) だが、Webアプリケーションの開発という文脈においては 動的ロードを想定したXSライブラリの利用がほとんどであるはず…… 😮 36

Slide 37

Slide 37 text

Perlランタイム DBD::mysql (のPerl部分) DBD::mysql (のXS由来部分) 動的ロード libmysql- client 動的リンク DBD::mysqlの典型的な利用イメージ DBD::mysqlのXS由来部分から、どうlibmysqlclientをリンクするか話も当然ありまして…… https://metacpan.org/dist/DBD-mysql/view/lib/DBD/mysql/INSTALL.pod 💁 DBD::mysql 37

Slide 38

Slide 38 text

Perlランタイム DBD::mysql (のPerl部分) DBD::mysql (のXS由来部分) libmysql- client https://github.com/perl5-dbi/DBD-mysql /blob/6465c04c62d23ce42b08b90ea336 3630187e1739/dbdimp.h#L22-L24 #include して… 実装チラ見 38

Slide 39

Slide 39 text

Perlランタイム DBD::mysql (のPerl部分) DBD::mysql (のXS由来部分) libmysql- client https://github.com/perl5-dbi/DBD-mysql /blob/6465c04c62d23ce42b08b90ea336 3630187e1739/Makefile.PL#L423-L469 ビルド時の設定 あれこれ 実装チラ見 39

Slide 40

Slide 40 text

Perlランタイム Perlプログラム (*.pl, *.pm) 40

Slide 41

Slide 41 text

Perlランタイム Perlプログラム (*.pl, *.pm) イラスト出典: いらすとや 手のひらで踊らされる人のイラスト(男性) https://www.irasutoya.com/2018/03/blog-post_850.html ランタイムの手のひらの上 41

Slide 42

Slide 42 text

Perlランタイム Perlプログラム (*.pl, *.pm) XS 42

Slide 43

Slide 43 text

Perlランタイム Perlプログラム (*.pl, *.pm) XS イラスト出典: いらすとや 相撲の取組のイラスト https://www.irasutoya.com/2017/04/blog-post_51.html 相撲の土俵のイラスト(斜め) https://www.irasutoya.com/2017/06/blog-post_605.html ランタイムと同じ土俵に立つ 43

Slide 44

Slide 44 text

「ネイティブ拡張」? - perlxstut - Tutorial for writing XSUBs (Perl) https://perldoc.perl.org/perlxstut - “a Perl extension” - Gems with Extensions (RubyGems) https://guides.rubygems.org/gems-with-extensions/ - “Many gems use extensions to wrap libraries …” - Extending Python with C or C++ (Python) https://docs.python.org/3/extending/extending.html - “extension modules” - C++ addons (Node.js) https://nodejs.org/api/addons.html - “Addons are dynamically-linked shared objects written in C++” 44

Slide 45

Slide 45 text

「ネイティブ拡張」? - perlxstut - Tutorial for writing XSUBs (Perl) https://perldoc.perl.org/perlxstut - “a Perl extension” - Gems with Extensions (RubyGems) https://guides.rubygems.org/gems-with-extensions/ - “Many gems use extensions to wrap libraries …” - Extending Python with C or C++ (Python) https://docs.python.org/3/extending/extending.html - “extension modules” - C++ addons (Node.js) https://nodejs.org/api/addons.html - “Addons are dynamically-linked shared objects written in C++” 45

Slide 46

Slide 46 text

「ネイティブ拡張」? - 単に “extension” や “addon” くらいが一般的なのかも - このトークでは、ネイティブコードの呼び出しを伴うこ とを強調するために「ネイティブ拡張」と呼ぶことにし ます - (そこまで気にしなくても、たいてい通じるでしょう…) 46

Slide 47

Slide 47 text

余談 47

Slide 48

Slide 48 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood ✅ - XS、「ネイティブ拡張」とは ✅ - XSモジュールインストール under the hood 48

Slide 49

Slide 49 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood - XS、「ネイティブ拡張」とは - XSモジュールインストール under the hood 49

Slide 50

Slide 50 text

こういうことやりませんでしたか $ cpanm -L local DBD::mysql \ --configure-args="--cflags='$(pkg-config --cflags mysqlclient)' \ --libs='$(pkg-config --libs mysqlclient)'" $ CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" carton install 50

Slide 51

Slide 51 text

Perlランタイム Perlプログラム (*.pl, *.pm) 共有 ライブラリ 動的ロード 共有 ライブラリ 動的リンク 「ネイティブライブラリのラッパー」 的なシーン 51 再掲

Slide 52

Slide 52 text

Perlランタイム Perlプログラム (*.pl, *.pm) 共有 ライブラリ 動的ロード 共有 ライブラリ 動的リンク 「ネイティブライブラリのラッパー」 的なシーン どれを? どれを? 🤔 52

Slide 53

Slide 53 text

Perlランタイム Perlプログラム (*.pl, *.pm) 共有 ライブラリ 動的ロード 共有 ライブラリ 動的リンク 「ネイティブライブラリのラッパー」 的なシーン CPAN モジュールの 単位 53

Slide 54

Slide 54 text

Perlランタイム Perlプログラム (*.pl, *.pm) 共有 ライブラリ 動的ロード 共有 ライブラリ 「ネイティブライブラリのラッパー」 的なシーン XSから生成される共有ライブラリと、 OSのどこかにあるライブラリとの間の関係 動的リンク 54

Slide 55

Slide 55 text

こういうことやりませんでしたか $ cpanm -L local DBD::mysql \ --configure-args="--cflags='$(pkg-config --cflags mysqlclient)' \ --libs='$(pkg-config --libs mysqlclient)'" $ CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" carton install XSから生成される共有ライブラリを ビルドするにあたり、 OSのどこにあるライブラリと 紐づけるかの指定 55

Slide 56

Slide 56 text

大変 - ツール・ライブラリごとに指定方法が違う - 環境変数、コマンドラインオプション、… - Makefile.PL、Build.PL は普通のPerlスクリプトなの で、なんでもできるという側面 56

Slide 57

Slide 57 text

Perlランタイム DBD::mysql (のPerl部分) DBD::mysql (のXS由来部分) mysql_configコマンドを 呼び出したり 環境変数やオプションで指 定できたり (写ってない) DBD::mysqlの Makefile.PL再び 57 https://github.com/perl5-dbi/DBD-mysql/ blob/6465c04c62d23ce42b08b90ea33636 30187e1739/Makefile.PL#L423-L469

Slide 58

Slide 58 text

こういう苦労話 - 最近は以前ほど見なくなった…かも? - コンパイル済みバイナリ込みでの配布が一般化 - Dockerエコシステムの普及 - いわゆる手元環境も、Dev ContainersやDocker Composeなどで一元管理するのが一般化したことで、 環境の差異に由来する困りごとは減ってそう 58

Slide 59

Slide 59 text

ところで - Perlのモジュールをpacman -Sできるように するためのガイドがArchWikiにあり、これが 一番まとまっていてわかりやすいかも - Perl パッケージガイドライン - ArchWiki 59

Slide 60

Slide 60 text

https://gitlab.archlinux.org/arch linux/packaging/packages/perl-d bd-mysql/-/blob/main/PKGBUILD ?ref_type=heads 60

Slide 61

Slide 61 text

XSモジュールのインストールその前に - CPANモジュールインストール under the hood ✅ - XS、「ネイティブ拡張」とは ✅ - XSモジュールインストール under the hood ✅ 61

Slide 62

Slide 62 text

XSモジュールにまつわるトラブル (俺調べ) 62

Slide 63

Slide 63 text

XSモジュールにまつわるトラブル (俺調べ) 63

Slide 64

Slide 64 text

perldocの歩き方 - perlxs, perlapi など perl*** みたいな名前の ドキュメントがたくさん - C APIもしっかりドキュメントがある - 例: perlguts (Perl APIの導入) を読むには… - https://perldoc.perl.org/perlguts - https://perldoc.jp/docs/perl/perlguts.pod - $ perldoc perlguts 64

Slide 65

Slide 65 text

https://perldoc.jp/index/core#:~:text=perl%20%E7 %94%A8%E8%AA%9E%E9%9B%86-,%E5%86%85%E 9%83%A8%E3%81%A8C%E8%A8%80%E8%AA%9E %E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BF %E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC %E3%82%B9,-perlembed%20%2D%20C%20%E3%83 %97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83 %A0 65

Slide 66

Slide 66 text

というわけで 66

Slide 67

Slide 67 text

実践! XS コードリー ディング 67

Slide 68

Slide 68 text

お品書き - Cpanel::JSON::XS - https://github.com/rurban/Cpanel-JSON-XS - DBD::mysql - https://github.com/perl5-dbi/DBD-mysql - Inline::Ruby - https://github.com/shlomif/Inline-Ruby 68

Slide 69

Slide 69 text

Cpanel::JSON::XS use Cpanel::JSON::XS qw(encode_json decode_json); my $encoded = encode_json( { foo => 1, bar => [2, 3] } ); my $parsed = decode_json('{"foo":1,"bar":[2,3]}'); 69

Slide 70

Slide 70 text

encode_json で grep すると関数定義が2個 どっちが本物? 70

Slide 71

Slide 71 text

“キーワード MODULE は XS コードの始まりと、定義する関数のパッケージ を指定するのに使われます。 キーワード MODULE よりも前にあるテキスト はCプログラムとして扱われ、 POD が除去されますが、それ以外は何の変更 も加えられずに出力されます” https://perldoc.jp/docs/perl/5.8.8/perlxs.pod#The32MODULE32Keyword 71

Slide 72

Slide 72 text

72

Slide 73

Slide 73 text

引数 ALIAS: 関数の別名指定 「XSUB」 73

Slide 74

Slide 74 text

XSUB - perldoc.jp/docs/perl/perlxs.pod - “XSUB は XS インターフェースの基本単位を形成し ます。xsubpp コンパイラによるコンパイル後、 それ ぞれの XSUB は Perl 呼び出し規則と C 呼び出し規則 の間の糊を提供する C 関数定義となります” - XSUB1個 = Perl上での関数定義1個 74

Slide 75

Slide 75 text

PPCODE: 実装部分 (引数・返り値のスタック操作アリ) 75

Slide 76

Slide 76 text

PUTBACK 〜 SPAGAIN Perlランタイムのスタックの退避〜復帰 XPUSHs(SV* sv) svをスタックにプッシュ ここではscalarが XSUBの返り値となる 76

Slide 77

Slide 77 text

SV - see perlguts - SV: Scalar Value - とる値: “整数 (IV)、符号なし整数 (UV)、 倍精度 (NV)、文字列 (PV)、その他のスカラ (SV)” - ほか AV (Array Value), HV (Hash Value), RV (Reference Value), … 77

Slide 78

Slide 78 text

https://speakerdeck.com/hatena/remote-internship-2023-perl SVのなかでも… 文字列 = PV 整数 = IV リファレンス = RV 78

Slide 79

Slide 79 text

配列 = AV https://speakerdeck.com/hatena/remote-internship-2023-perl 79

Slide 80

Slide 80 text

ハッシュ = HV https://speakerdeck.com/hatena/remote-internship-2023-perl 80

Slide 81

Slide 81 text

スタックの管理 - Perlにおける関数の引数・戻り値のスタック の管理が必要 - 引数をスタックから取得 - 戻り値をスタックに積む - … - スタックの管理 = スタックポインタの操作 81

Slide 82

Slide 82 text

スタックの管理 - perldocの各所に説明がある - https://perldoc.perl.org/perlinterp#STACKS - https://perldoc.perl.org/perlguts#XSUBs-and-t he-Argument-Stack - ほか perlsub, perlfunc, perlcall 82

Slide 83

Slide 83 text

スタックの管理 - PUTBACK 〜 SPAGAIN - PUTBACK: XSUB内でのローカル変数なスタックポイ ンタの内容を、Perlランタイムのそれ (PL_stack_sp) に書き込み - SPAGAIN: ↑の逆 (Perlランタイム → XSUB内のローカ ル変数スタックポインタ) 83

Slide 84

Slide 84 text

PUSHMARK(SP) - PUTBACK間で 引数をスタックに PUSHs call_sv: Perlの関数呼び出し PUSHsされている物体が引数になる。 ここではmethod変数がサブルーチン リファレンス (see L1766) Perl上の関数呼出しの例 84

Slide 85

Slide 85 text

XSの関数定義 (XSUB) じゃな かった方の関数を呼び出し。 実処理はこっち 85

Slide 86

Slide 86 text

"コンテクストポインタ" を 受け取るマクロ mortalフラグのセット スコープを抜ける際に参照カウンタを デクリメント SvPVX: PV (文字列) へのポインタ SvEND: PV (文字列) の終端位置への ポインタ XSの関数定義 (XSUB) じゃなかった方の encode_jsonも見る 86

Slide 87

Slide 87 text

SvPOK_only: “SV に対し、その SV が文字列であり、 他の OK ビットをすべてディセーブルにするように指 示します。また、UTF-8 ステータスをオフにします” (perlapi) aTHx_: コンテキストポインタを 「渡す」マクロ SVの 文字数セット SVのUTF-8フラグを立てる encode_svがSV一つを エンコードする処理 87

Slide 88

Slide 88 text

encode_sv() - シリアライズ本丸的な関数 - https://github.com/rurban/Cpanel-JSON-XS/bl ob/2c3ad61969205b9a85749ea55e1af81f422e 96f7/XS.xs#L1940-L2729 - 789行 (!) - ざっくり: 型ごとに場合分けしてエンコード 88

Slide 89

Slide 89 text

ここまでの雑感 - xsubppにより前処理される部分と、PerlのC APIの部分と、各ライブラリの実装とが渾然一 体となっている - Perlランタイムを正常に動かすための変数の操作も、 xsubppやCマクロで隠蔽されている部分が多い - APIの命名に規則性はあったりもするが、全部を覚え るのは大変 89

Slide 90

Slide 90 text

ビルドしてみよう 90

Slide 91

Slide 91 text

xsubpp before/after 91

Slide 92

Slide 92 text

92 xsubppを 直実行もできるぞ!

Slide 93

Slide 93 text

objdumpしてみよう 93

Slide 94

Slide 94 text

DBD::mysql - “MySQL driver for the Perl5 Database Interface (DBI)” - DBI: Database Interface - DBD: Database Driver - DBD::mysql の他には DBD::Pg, DBD::SQLite など - DBD::** implements DBI 的な関係 94

Slide 95

Slide 95 text

DBD::mysql - https://metacpan.org/pod/DBI::DBD に ドライバーの書き方ドキュメントがある - めっちゃ長い! - まず https://metacpan.org/pod/DBI を読め、という のが最初に書かれている 95

Slide 96

Slide 96 text

ざっくり - DBI曰く、XSでドライバーを書くときは… - SELECT した結果を取得するために、dbdimp.c に dbd_st_fetch() 関数を実装してね、という世界観 - INSERT などのために、dbd_st_execute() を以下 略 96

Slide 97

Slide 97 text

https://github.com/perl5-dbi/DBD-mysql/blob/64 65c04c62d23ce42b08b90ea3363630187e1739/d bdimp.c#L2956-L3083 97 dbd_st_execute

Slide 98

Slide 98 text

https://github.com/perl5-dbi/DBD-mysql/blob/64 65c04c62d23ce42b08b90ea3363630187e1739/d bdimp.c#L2956-L3083 コンテクスト変数を 取得できるようにするマクロ DBIの初期化処理 sth がハッシュリファレ ンスかどうかチェック https://perldoc.perl.org /perlguts#References 98

Slide 99

Slide 99 text

sth (statement handler) に紐づくキャッシュのクリア Nullav (AVのヌルポインタ) の代入と、 SvREFCNT_dec でのリファレンスカウ ントの減算 hv_fetch: ハッシュの値取得 ここでは “Statement” がキーのものを 取得している 99

Slide 100

Slide 100 text

サーバサイドでのプリペアド ステートメント処理時の分岐 内部ではmysql_stmt_execute() (MySQL C API) を実行 100

Slide 101

Slide 101 text

mysql_send_query() asyncクエリ有効なら mysql_real_query() (MySQL C API) mysql_insert_id(): insertしたauto incrementの カラムの値取得 101

Slide 102

Slide 102 text

102

Slide 103

Slide 103 text

Inline::Ruby 103

Slide 104

Slide 104 text

Inline::Ruby - ネタモジュールと思うなかれ - 実装はガチ 104

Slide 105

Slide 105 text

https://metacpan.org/dist/Inlin e-Ruby/view/lib/Inline/Ruby.pod #Low-Level-Inline::Ruby 105

Slide 106

Slide 106 text

上に PREFIX = my_ 指定があるので これが rb_eval 関数の定義になる (see perlxs) PREINIT: typemap 機能に影響されずに 変数宣言をするセクション 106

Slide 107

Slide 107 text

rb_rescue2, rb_str_new2 は Ruby の C API rb2pl() が本丸っぽさ 107

Slide 108

Slide 108 text

VALUE型 = Rubyオブジェクト newSViv = IV (integer) から SV を生 成 newSVnv = NV (double型) から SV newSVpvn = PV (char *) とその長さか ら SV https://docs.ruby-lang.org/en/ master/extension_rdoc.html rb2pl (!!) 108

Slide 109

Slide 109 text

rb_ary_entry でRubyの配列 から値を取り出し、その要素を 再帰的に rb2pl し、av_push で Perlの配列に追加 newRV_noinc() で AV (retval) からリファレンス を取得 _noinc はリファレンスカ ウントを増加させない版 API newAVで AV (Array Value) を 作成 newHVで HV (Hash Value) を 作成 109

Slide 110

Slide 110 text

ハッシュのキーだけの配列を 作り… rb_hash_arefでハッシュ の中身取得 キーがStringでなければ .to_s hv_storeでPerlのハッシュ に格納 110

Slide 111

Slide 111 text

typemap - see perlxstypemap - Cレベルの型 ←→ Perlのデータ型の変換機構 - char * を簡単にPVにしたい、みたいなことができる - xsubppで処理されるので、それが嬉しくないという ときは実装を PPCODE: セクションに書く…というの がCpanel::JSON::XSで出てきていた 111

Slide 112

Slide 112 text

XSモジュールにまつわるトラブル (俺調べ) 112 ✔

Slide 113

Slide 113 text

XSモジュールにまつわるトラブル (俺調べ) 113 ✗

Slide 114

Slide 114 text

イラスト出典: いらすとや 氷山の一角のイラスト https://www.irasutoya.com/2016/08/blog-post_175.html

Slide 115

Slide 115 text

改めて List::Util::min https://github.com/P erl/perl5/blob/c7aed 9f/cpan/Scalar-List-U tils/ListUtil.xs#L270- L319 115

Slide 116

Slide 116 text

改めて List::Util::min slu_sv_value: SVからUVかIVの値を 取り出すマクロ 116

Slide 117

Slide 117 text

改めて List::Util::min 117

Slide 118

Slide 118 text

改めて List::Util::min active magic = 演算子オーバーロード amagic_call(SV *left, SV *right, int method, int dir) 118 ix: ALIASごとのインデックス これを使ってmax/minを一つの XSUBで実装している

Slide 119

Slide 119 text

🍵 119

Slide 120

Slide 120 text

XS 別解 - FFI - ex. https://metacpan.org/pod/FFI::Platypus - 別バイナリ化 + プロセス間通信 - WASM - XSと比べるとオーバーヘッドがあったり、ラ ンタイムの機能拡張は難しかったり 120

Slide 121

Slide 121 text

121

Slide 122

Slide 122 text

AI? - XSの既存実装調査は、AI丸投げでもそこそこうま くいく - Perlのソースコードで定義されているはずのこれ何?みたい な質問でも、特別コンテキストを与えずともパッと答えてく れがち - とはいえ、概略的なところからエコシステムまで薄 く広い知識を持っておけるとスムーズ (それはそ う) 122

Slide 123

Slide 123 text

まとめ - CPANモジュール、XSモジュールを取り巻く エコシステムについておさらいした - XS言語のコンセプトや基本的な構文から、 APIのあらましについて入門した - SV/AV/HV、スタック操作、参照カウント、… - Perlランタイムのソースコードに入門 (?) した 123

Slide 124

Slide 124 text

ここはYet Another Perl Conference - 今日紹介したモジュールのauthorや contributorの方がこの会場にたくさんい らっしゃるはず!!!!!! - 懇親しましょう!!!!!! 124

Slide 125

Slide 125 text

XSを書きたい人向け おすすめ参考文献 - Minillaを使ったモダンなCPANモジュール開発(1) https://gihyo.jp/dev/serial/01/perl-hackers-hub/005001 - https://metacpan.org/pod/Minilla - C による Perl 拡張入門 https://xsubtut.github.io/ - XS基礎文法最速マスター https://gfx.hatenadiary.org/entry/20100202/1265091606 125

Slide 126

Slide 126 text

(おまけ) 超私的・大分観光案内 - JR九州の割引きっぷがある (九州ネットきっぷ 他) - 別府の市営温泉に入ろう (“別府 市営温泉” で検索) - 別府で冷麺を食べよう (“別府冷麺” で検索”) - 焼鳥、アジ、ヒラメを食べよう - やまなみハイウェイをドライブしよう - ホバークラフトに乗ってみて感想教えてくだ さい (乗ったことない…) 126

Slide 127

Slide 127 text

127

Slide 128

Slide 128 text

hatena.co.jp/recruit 128 128