Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RubyVM を PHP で実装する 〜Hello World を出力するまで〜

memory
March 09, 2024

RubyVM を PHP で実装する 〜Hello World を出力するまで〜

PHPerKaigi 2024

memory

March 09, 2024
Tweet

More Decks by memory

Other Decks in Programming

Transcript

  1. Ί΋Γʔ m3m0r7 ෳ਺ͷελʔτΞοϓ΍্৔اۀͰΤϯδ χΞɼEMɼTLɼࣥߦ໾һ CTO ͷܦݧΛܦ ΔɻRuby on Rails ΍

    Go Λ࢖༻͍ͯ͠Δ גࣜձࣾΤϯϖΠ΁ 2023 ೥ 7 ݄ʹΤϯδ χΞͱͯ͠δϣΠϯɻ2023 ೥ 10 ݄͔Β EM ͱͯ͠ಇ͍͍ͯ·͢ɻ  memory1994 m3m0r7
  2. 

  3.  աڈʹ JVM (Java Virtual Machine) Λ PHP Ͱ࣮૷ͨ͠಺༰Ͱొஃ͓ͯ͠Γ·͢ ※ݱࡏࢲ͸

    BASE גࣜձࣾΛୀ৬͓ͯ͠Γɼ
 ࢿྉ͸౰࣌ͷ΋ͷΛҾ༻͓ͯ͠Γ·͢ɻ ※ݱࡏࢲ͸ גࣜձࣾ GameWith Λୀ৬͓ͯ͠Γɼ
 ࢿྉ͸౰࣌ͷ΋ͷΛҾ༻͓ͯ͠Γ·͢ɻ
  4. VM ͱ͸ʁ - VM ͱ͸Ծ૝Ϛγϯͷ͜ͱΛࢦ͠ɼίϯϐϡʔλʔͷಈ࡞ΛΤϛϡϨʔγϣϯ ʢ࠶ݱʣͤ͞Δ΋ͷͰ͢ɻ - VM ্Ͱ Linux/Unix

    Λಈ͔ͨ͠Γ͍ͯ͠Δํ΋͍Δͱࢥ͍·͢ɻ - VM ΛՄೳͱ͢Δ୅දతͳ΋ͷ͸ KVM (Kernel-based Virtual Machine) ͩͬ ͨΓɼHyper-V (Windows) ͩͬͨΓɼVirtualBox ͳͲ͕ྫʹ্͕ΔͰ͠ΐ ͏ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  5. VM ͱ͸ʁ - Type-1, Type-2 ͱ͍͏෼ྨ͕͋ΓɼType-1 ͸ϕΞϝλϧʢϋʔυ΢ΣΞʹμ ΠϨΫτͳ΋ͷʣɼType-2 ͸ϗετܕʢطଘͷ OS

    ্Ͱಈ͘΋ͷʣͰ͢ɻ͜ ΕΒΛ૯ͯ͡ Hyper VisorʢϋΠύʔόΠβʔʣͱݺͿ͜ͱ͕͋Γ·͢ɻ - Docker ΋Ծ૝Ϛγϯʹࣅ͍ͯ·͕͢ɼݫີʹ͸ҟͳΓ·͢ɻVM ͸׬શʹ෼ ཭͞Εͨήετ OS ͷΧʔωϧΛ͍࣋ͬͯΔͷʹରͯ͠ɼDocker ͸ϗετ OS ͷΧʔωϧΛڞ༗͍ͯ͠·͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  6. VM ͱ͸ʁ - ͱ͍͏͜ͱΛॻ͖·͕ͨ͠ɼZend VMɼJVMɼ RubyVM ͸ VM Ͱ͸͋Δ΋ͷ ͷɼ͜ͷఆٛʹ͸ݫີʹ͸౰ͯ͸·Γ·ͤΜɻ

    - ͔͠͠ɼઌ΄Ͳॻ͍ͨʮVM ͱ͸Ծ૝Ϛγϯͷ͜ͱΛࢦ͠ɼίϯϐϡʔλʔͷ ಈ࡞ΛΤϛϡϨʔγϣϯʢ࠶ݱʣͤ͞Δ΋ͷͰ͢ɻʯͱ͸ಉ౳Ͱ͋ΔͱղऍͰ ͖·͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  7. VM ͱ͸ʁ - CPU ͸໋ྩηοτʹैͬͯಈ࡞͠·͢ɻ͜ͷ໋ྩηοτ͸਎ۙͳ΋ͷͰݴ͑ ͹ Intel ΍ ARM ͳͲʹ΋͋ΓɼͦΕͧΕҟͳΓ·͢ɻ

    - ͜ͷ CPU ͷ໋ྩηοτΛஞ࣮࣍ߦͤ͞Δ͜ͱ͕ίϯϐϡʔλʔ͕ಈ͘ݪཧͷ ҰͭͰ͕͢ɼZend VM ΍ JVMɼRubyVM ʹ΋໋ྩηοτ͕͋Γɼ·ΔͰίϯ ϐϡʔλʔ͕ಈ͘ݪཧʹଇ࣮ͬͯߦ͞Ε͍ͯ·͢ɻ - ͦͷͨΊɼΤϛϡϨʔγϣϯͱ͍͏จ຺Ͱ͸ VM Ͱ͋ΔͱղऍͰ͖ΔͷͰ͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  8. VM ͱ͸ʁ - ͦͯ͠ɼ͜ΕΒͷ VM ͷ΄ͱΜͲ͸ελοΫϚγϯͱͯ͠ಈ࡞͠·͢ɻ - ଞʹҰൠతͳ΋ͷ͸ϝϞϦϨδελϚγϯͳͲ͕͋Γ·͢ɻ͜Ε͸ Intel ΍

    ARM ͳͲ͕֘౰͠·͢ɻ - ຊτʔΫͰ͸ɼϝϞϦϨδελϚγϯʹ͍ͭͯͷղઆ͸ׂѪ͠·͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  9. ελοΫϚγϯͬͯͳʹʁ - ελοΫϚγϯͱ͸ɼσʔλߏ଄ͷҰͭͰσʔλ Λ௥Ճʢϓογϡʣ͠ͳ͕Βɼ໋ྩηοτʹΑͬ ͯͦͷ௥Ճͨ͠σʔλΛऔಘʢϙοϓʣͯ͠ɼԿ ͔͠ΒͷܭࢉΛߦ͍ͬͯ͘ίϯϐϡʔλͷΞʔΩ ςΫνϟͰ͢ɻ - ྫ͑͹ʮελοΫ͔Β 2

    ͭ஋Λϙοϓ͠Ճࢉͤ͞ ͨ΋ͷΛϓογϡ͢Δʯͱ໋͍ͬͨྩηοτ΋͋ Γ·͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ 1 ճ໨ʹϓογϡ͞Εͨσʔλ 2 ճ໨ʹϓογϡ͞Εͨσʔλ N ճ໨ʹϓογϡ͞Εͨσʔλ ộ σʔλΛϓογϡ σʔλΛϙοϓ Կ͔͠Βͷ໋ྩηοτͰ σʔλΛ࢖༻ Կ͔͠Βͷ໋ྩηοτͰ σʔλΛελοΫʹ௥Ճ
  10. ໋ྩηοτͬͯͳʹʁ - ͨͩݴ͑Δͷ͸ɼࣅͨΑ͏ͳ໋ྩηοτ͕େମͲͷ VM ʹ΋ଘࡏ͍ͯ͠·͢ɻ - ໋ྩηοτ͸ͲΕ΋୯७ԽΛ໨ࢦ͍ͯ͠Δ܏޲͕ଟ͍΋ͷ͕ଟ͍Ͱ͢ɻ୯७Խ Λ໨ࢦ͢ઃܭࢥ૝ͷ͜ͱΛ RISC ʢReduced

    Instruction Set Computerʣͱ ݴ͍·͢ɻٯʹ CISC (Complex Instruction Set Computer) ͱ͍͏ෳࡶͰ͸ ͋Δ໋͕ྩ਺ΛۃྗݮΒͨ͠λΠϓͷ΋ͷ΋͋Γ·͢ɻ - ࠷ۙͰ͸͋Μ·Γࠩҟ͕ͳ͍ͱ΋ݴΘΕ͍ͯ·͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  11. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output - constadd ໋ྩ͸ 1 ͭͷΦϖϥϯυΛऔΓɼͦΕΛελοΫ ʹϓογϡ͢Δ໋ྩ - plus ͸ελοΫ͔Β 2 ͭ஋Λϙοϓ͠ɼͦΕΛՃࢉͨ͠΋ͷ ΛελοΫʹϓογϡ͢Δ໋ྩ - output ͸ελοΫ͔ΒҰͭϙοϓ͠ग़ྗ͢Δ໋ྩ - ্هͷ 3 ͭͷ໋ྩͰ࣮ݱՄೳͰ͢ɻ͜ͷҰ࿈ͷྲྀΕΛ໋ྩ γʔέϯεͱݴͬͨΓ͠·͢ɻ
  12. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output ελοΫ 1 ελοΫʹ 1 Λϓογϡ
  13. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output ελοΫ 1 ελοΫʹ 2 Λϓογϡ 2
  14. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output ελοΫ 1 2 ͭͷσʔλΛϙοϓ 2 3 Ճࢉͨ݁͠ՌΛϓογϡ
  15. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output ελοΫ 3 ελοΫʹ 3 Λϓογϡ 3
  16. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output ελοΫ 3 2 ͭͷσʔλΛϙοϓ 3 6 Ճࢉͨ݁͠ՌΛϓογϡ
  17. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ  VM (Virtual Machine)

    ʹ͍ͭͯ constadd (operand: 1) constadd (operand: 2) constadd (operand: 3) plus plus output ελοΫ 6 1 ͭͷσʔλΛϙοϓ
  18. 1 + 2 + 3 Λٙࣅ໋ྩηοτͰܭࢉ͢Δ - ֓Ͷ΄ͱΜͲͷ VM ͸ઌఔͷղઆͷΑ͏ͳܗͰ࣮૷͞Ε͍ͯ·͢ɻ͜ΕΒΛԠ

    ༻ͨ͠΋ͷ͕ Zend VM ͩͬͨΓɼJVM ͩͬͨΓɼͦͯ͠ຊτʔΫͷझࢫͰ͋ Δ RubyVM Ͱ͢ɻ - Ͱ͸ RubyVM ͸ͲͷΑ͏ʹ࣮૷͢ΔͷͰ͠ΐ͏͔ɻ࣍ͷηΫγϣϯͰղઆ͠ ͍͖ͯ·͢ɻ  VM (Virtual Machine) ʹ͍ͭͯ
  19. RubyVM ͱ͸ - RubyVM ͸ YARV (Yet Another Ruby Vm)

    ͱ΋ݺ͹Ε Sasada Koichi (@koichisasada) ͞Μ͕ Ruby ޲͚ͷԾ૝Ϛγϯͱ࣮ͯ͠૷͖ͯͨ͠΋ͷͰ͢ [1]ɻ - YARV ͸୺తʹݴ͑͹ɼISeqʢInstruction Sequenceʣͱݺ͹ΕΔ໋ྩγʔέ ϯεʢ࣮ߦ͢΂໋͖ྩͷҰཡʣͱɼͦͷ໋ྩγʔέϯεʹର͢Δϝλ৘ใͷू ߹Ͱ͢ɻ  RubyVM ͷ͘͠Έ [1]: https://sitaramshelke.medium.com/inside-rubyvm-967b25e234db
  20. RubyVM ͱ͸ - Լਤ͸ Hello World! Λग़ྗ͢ΔͨΊͷ YARV Ͱ͢ɻ 

    RubyVM ͷ͘͠Έ Hello World! ͱ͍͏จࣈྻ͕ݟ͑·͢Ͷ
  21.  The header section (36 bytes) The payload section The

    instruction sequence offsets section (The information is each of instruction sequence offsets; N>0 * 4 bytes) The global object offsets section (The information is each of global object offsets; N>0 * 4 bytes) The extra data (if embedded extra data; N>=0 bytes) A part of instruction sequences A part of global objects The RUBY_PLATFORM name section (string) An information of string / class / fi xed number / bool types and data An information of instruction sequence section (In normally, 44 info * 4 bytes = 176 bytes notice: no considered hamming weight) ộ A code section (N>0 bytes) ộ A local table section (N>=0 bytes) A call info entry section (N>=0 bytes) ộ The structure of YARV The alignment section (Filled by 0xff to align every 2 bytes) ※ Ruby ຊମͷ C ࣮૷ΛಡΜͰࢲ͕ղऍͨ͠΋ͷΛςΩετɾਤʹදͨ͠΋ͷͰ͢ɻ
  22.  The header section (36 bytes) The payload section The

    instruction sequence offsets section (The information is each of instruction sequence offsets; N>0 * 4 bytes) The global object offsets section (The information is each of global object offsets; N>0 * 4 bytes) The extra data (if embedded extra data; N>=0 bytes) A part of instruction sequences A part of global objects The endian section (2 bytes) An information of string / class / fi xed number / bool types and data An information of instruction sequence section (In normally, 44 info * 4 bytes = 176 bytes notice: no considered hamming weight) ộ A code section (N>0 bytes) ộ A local table section (N>=0 bytes) A call info entry section (N>=0 bytes) ộ The structure of YARV The alignment section (Filled by 0xff to align every 2 ※ Ruby ຊମͷ C ࣮૷ΛಡΜͰࢲ͕ղऍͨ͠΋ͷΛςΩετɾਤʹදͨ͠΋ͷͰ͢ɻ The word size section (2 bytes)
  23.  The header section (36 bytes) The payload section The

    instruction sequence offsets section (The information is each of instruction sequence offsets; N>0 * 4 bytes) The global object offsets section (The information is each of global object offsets; N>0 * 4 bytes) The extra data (if embedded extra data; N>=0 bytes) A part of instruction sequences A part of global objects An information of string / class / fi xed number / bool types and data An information of instruction sequence section (In normally, 44 info * 4 bytes = 176 bytes notice: no considered hamming weight) ộ A code section (N>0 bytes) ộ A local table section (N>=0 bytes) A call info entry section (N>=0 bytes) ộ The structure of YARV The alignment section (Filled by 0xff to align every 2 ※ Ruby ຊମͷ C ࣮૷ΛಡΜͰࢲ͕ղऍͨ͠΋ͷΛςΩετɾਤʹදͨ͠΋ͷͰ͢ɻ The endian section (2 bytes) The word size section (2 bytes) Platform name section ͕
 endian section ͱ word size section ʹมߋɻ
 Ruby 3.2 → 3.3 Ͱ YARV ͷߏ଄͸͜ΕҎ֎มߋͳ͠ɻ
  24. RubyVM ͱ͸ - Ruby Ͱ Hello World! Λग़ྗ͢Δʹ͸࣮͸ࠨਤͷ ίʔυͰॆ଍͠·͢ɻ͔͠͠ɼYARV ʹͳΔͱ࿩

    ͕มΘΓ·͢ɻ - RubyVM ʹݶΒͣ VM Λ࣮૷͠ɼHello World Λ ग़ྗ͢Δ·Ͱَ͕໳Ͱ͢ɻ໋ྩηοτΛ࣮૷͢Δ ͷ͸ͦ͜·Ͱۤ࿑͠·ͤΜ͕ɼ໋ྩηοτΛΤ ϛϡϨʔτ͢Δ VM ͦͷ΋ͷΛ࣮૷͢Δͷʹۤ࿑ ͠·͢ɻͦΕָ͕ܹࢗ͘͠తͳͷͰ͢ɻ  RubyVM ͷ͘͠Έ
  25. 

  26. ͦ΋ͦ΋Ͳ͏΍࣮ͬͯ૷͢Δͷʁ - JVM ʹ͸ Java Virtual Machine Speci fi cation[1]

    ͱݺ͹ΕΔυΩϡϝϯτ͕ ॆ࣮͍ͯ͠·͢ɻ - Java ͸اۀओମͰ͕͢ɼRubyVM ͷ৔߹ίϛϡχςΟʹΑͬͯ։ൃ͞Ε͍ͯ Δ͜ͱ΋͋Γ༗ࢤͨͪʹΑͬͯυΩϡϝϯτͷ੔උ͕ͳ͞Ε͍ͯ·͕͢ VM ͷ ࣮૷ํ๏ʹݶͬͯݴ͑͹اۀओମͱൺֱ͢ΔͱͲ͏ͯ͠΋ݶք͕͋Γ·͢ɻ - ͦΜͳதɼRubyVM Λ࡞Δʹ͸Ͳ͏ͨ͠Β͍͍Ͱ͠ΐ͏͔ɻ  RubyVM ͷ࡞Γํ [1]: https://docs.oracle.com/javase/specs/jvms/se8/html/
  27. Ͳ͏΍ͬͯ PHP ͰόΠφϦΛಡΉͷ͔ - ͦ΋ͦ΋ YARV ϑΝΠϧΛੜ੒͢Δͱ͜Ζ͔ΒελʔτͰ͢ɻRuby ʹ͸ Instruction Sequence

    Λు͖ग़ͨ͢Ίͷɹ RubyVM::InstructionSequence.compile ͕༻ҙ͞Ε͍ͯ·͢ɻҎԼͷΑ͏ͳ ίϚϯυΛ༻͍ͯ HelloWorld.yarv ͱ͍͏ YARV ϑΝΠϧΛ࡞੒͠·͢ɻ  RubyVM ͷ࡞Γํ
  28. Ͳ͏΍ͬͯ PHP ͰόΠφϦΛಡΉͷ͔ - VM ࣮૷ʹ͓͍ͯɼΑ͘༻͍ΒΕΔ PHP ͷؔ਺͸ fread, fseek,

    unpack ͷ 3 छ ྨͰ͢ɻ͓͖֮͑ͯ·͠ΐ͏ɻ - ΋ͪΖΜ unpack Λ࢖Θͳ͍Ͱߦ͏࣮૷΋ϏοτԋࢉΛ༻͍Ε͹ՄೳͰ͢ɻϏο τԋࢉʹ͍ͭͯ͸ׂѪ͠·͢ɻ - PHP ͸ C ݴޠͱҧ͍ɼࢦఆͨ͠ܕͰόΠφϦΛಡΜͰ͘Εͳ͍ͷͰɼࢦఆͨ͠ Φϑηοτʢfseekʣ͔ΒจࣈྻͰҰ౓औಘʢfreadʣͨ͋͠ͱʹ਺஋ܕͳΓɼ ුಈখ਺఺ܕͳΓʹม׵ͯ͋͛͠Δඞཁʢunpackʣ͕ੜ͡·͢ɻ  RubyVM ͷ࡞Γํ
  29.  magic major version minor version size extra size global

    object list size iseq list offset global object list offset YARV ͷϔομʔ 4 byte 4 byte 4 byte 4 byte 4 byte 4 byte 4 byte 4 byte YARB (Yet Another Ruby Binary) ͱ͍͏ 
 ஋͕औಘͰ͖·͢ ίϯύΠϧ͞Εͨ Ruby ͷϝδϟʔόʔδϣϯ͕औಘ Ͱ͖·͢ɻྫͷ৔߹ʮ3ʯͰ͢ ίϯύΠϧ͞Εͨ Ruby ͷϚΠφʔόʔδϣϯ͕औಘ Ͱ͖·͢ɻྫͷ৔߹ʮ2ʯͰ͢ όΠφϦͷจࣈྻ௕͕औಘͰ͖·͢ Instruction Sequence ͕͍ͭ֨͘ೲ͞Ε͍ͯΔ͔Λ औಘͰ͖·͢ Ruby ͷγϯϘϧͷ৘ใ͕͍ͭ֨͘ೲ͞Ε͍ͯΔ͔Λ औಘͰ͖·͢ɻ όΠφϦ্ͷ Instruction Sequence ͷҐஔ৘ใΛऔ ಘͰ͖·͢ɻ Ruby ͷγϯϘϧͷ৘ใͳͲͷҐஔ৘ใ͕֨ೲ͞Εͯ ͍ΔϦετΛऔಘͰ͖·͢ɻ ͏·͘औಘͰ͖Δͱ
 ӈਤͷΑ͏ʹͳΓ·͢ iseq size 4 byte ಠࣗʹ௥Ճ͞ΕΔ֦ுσʔλͷจࣈྻ௕͕औಘͰ͖ ·͢
  30.  iseq list offset ʹΧʔιϧΛҠಈ iseq list size ෼ϧʔϓΛճ͠ 4

    όΠτ͝ͱͷ 
 Φϑηοτ৘ใΛऔಘ͢Δ global object list offset ʹΧʔιϧΛҠಈ global object list size ෼ϧʔϓΛճ͠ 4 όΠτ͝ͱ ͷΦϑηοτ৘ใΛऔಘ͢Δ Instruction Sequence ͷΦϑηοτ৘ใϦετΛऔಘ Global Object ͷΦϑηοτ৘ใϦετΛऔಘ
  31. Instruction Sequence ͷಡΈࠐΈ - RubyVM ͷ࣮૷ʹ͸ޮ཰తʹόΠφϦΛѻ͏ͨΊʹ ʮibf_(?:load|dump_write)_small_valueʯͱ͍͏֓ ೦͕͋Γ·͢[1]ɻ - ϋϛϯάॏΈ[2]

    ʢpopcount, population countʣͳ ͲΛ༻͍ͯόΠτ௕ΛՄมతʹѻ͍ͬͯΔ΋ͷͰ͢ɻ ࣮૷ྫ͸ࠨਤͷ௨Γɻ  RubyVM ͷ࡞Γํ [1]: https://github.com/ruby/ruby/blob/2f603bc4/compile.c#L11262-L11273
 [2]: https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%9F%E3%83%B3%E3%82%B0%E9%87%8D%E3%81%BF
  32. Instruction Sequence ͷಡΈࠐΈ - readSmallValue ͕࣮૷Ͱ͖ͨΒಡΈࠐΉ΂͖ 0 ൪໨ͷ Instruction Sequence

    ͷσʔλߏ଄ΛಡΈࠐΜͰ͍͖·͢ɻ - ͜ͷσʔλߏ଄ɼ࣮͸ͱͯ΋ڊେͰ Instruction Sequence ͷϝλ৘ใʢྫ֎ ςʔϒϧͳͲʣʹ֘౰͢Δ΋ͷͳͷͰ͕͢ɼͦͷϝλ৘ใͷ਺͸ 50 ݸҎ্͋ Γ·͢…ɻ - ͜ͷσʔλߏ଄શͯΛಡ·ͳͯ͘΋ɼHelloWorld ͷग़ྗͰ͋Ε͹໰୊ͳ͘Մ ೳͳͷͰɼׂѪͯ͠ඞཁͳ 4 ͭͷϝλ৘ใΛಡΈࠐΈ·͢ɻ  RubyVM ͷ࡞Γํ
  33. Instruction Sequence ͷಡΈࠐΈ - ۩ମతͳ࣮૷ྫ͸ Ruby ຊՈͷ࣮૷ʢ https://github.com/ruby/ruby/blob/ ruby_3_3/compile.c#L12514 ʣΛಡΉ͔ɼRubyVM

    on PHP ʢ https:// github.com/m3m0r7/rubyvm-on-php/blob/0.3.3.0/src/VM/Core/Runtime/ Kernel/Ruby3_3/InstructionSequence/ InstructionSequenceProcessor.php#L59 ʣͷ࣮૷Λ͝ཡ͍ͩ͘͞ɻ  RubyVM ͷ࡞Γํ
  34.  type iseq size bytecode offset bytecode size Instruction Sequence

    ΛಡΉ sv sv sv sv ※ sv ͸ small value ͷུ Instruction Sequence ͷΦϑηοτϦετ 0 ൪໨ 
 ʹΧʔιϧΛҠಈ
  35. Instruction Sequence ͷ࣮ߦ - ઌ΄ͲಡΈࠐΜͩ Instruction Sequence ͔Β $bytecodeO ff

    set, $iseqSize Λ༻͍ͯɼ໋ྩγʔέϯε Λऔಘ͠·͢ɻ - HelloWorld! Λग़ྗ͢Δࡍʹ࢖͏໋ྩηοτ͸ʮputself (18)ʯʮputstring (21)ʯʮopt_send_without_block (51)ʯʮleave (60)ʯͷ 4 छྨͰ͢ɻ - ࠨਤͷΑ͏ʹχʔϞχοΫΛॻ͖ग़͠·͢ɻ  RubyVM ͷ࡞Γํ ͜ͷΦϖϨʔγϣϯίʔυͱχʔϞχοΫͷඥ͚ͮ͸ https://github.com/ruby/ruby/blob/ruby_3_3/yjit/src/cruby_bindings.inc.rs#L669- L872 Ͱॻ͔Ε͍ͯ·͢
  36. Instruction Sequence ͷ࣮ߦ  RubyVM ͷ࡞Γํ putself putstring(operand: "HelloWorld!") leave

    opt_send_without_block ελοΫ ελοΫʹ࣮ߦதͷίϯςΩετΛ
 ϓογϡ ࣮ߦதͷίϯςΩετ
  37. Instruction Sequence ͷ࣮ߦ  RubyVM ͷ࡞Γํ putself putstring(operand: "HelloWorld!") leave

    opt_send_without_block ελοΫ ελοΫʹ HelloWorld! ͷ
 จࣈྻΛϓογϡ ࣮ߦதͷίϯςΩετ "HelloWorld!"
  38. Instruction Sequence ͷ࣮ߦ  RubyVM ͷ࡞Γํ putself putstring(operand: "HelloWorld!") leave

    opt_send_without_block ελοΫ 2 ͭͷελοΫΛϙοϓ ࣮ߦதͷίϯςΩετͷ 
 puts ϝιουΛݺͼग़͠ ࣮ߦதͷίϯςΩετ "HelloWorld!"
  39. Instruction Sequence ͷ࣮ߦ  RubyVM ͷ࡞Γํ putself putstring(operand: "HelloWorld!") leave

    opt_send_without_block ελοΫ ←࣮ߦͷऴྃॲཧɼฦΓ஋ΛૹΔ
  40. Instruction Sequence ͷ࣮ߦ - ࠨਤͷΑ͏ʹݺͼग़͠ݩͷ Main ΫϥεͱάϩʔόϧͳΦ ϒδΣΫτʹอଘ͞Ε͍ͯΔ஋ Λऔಘ͢ΔͨΊͷ loadObject

    Λ࣮૷͠·͢ɻ  RubyVM ͷ࡞Γํ ͜͜ͷ൪߸͸ https://github.com/ruby/ruby/blob/ruby_3_3/compile.c#L13303- L13336 ͷ 5 ൪໨ͷؔ਺Λࢦ͍ͯ͠·͢ (ibf_load_object_string)
  41. Instruction Sequence ͷ࣮ߦ - ࠨਤͷΑ͏ʹ HelloWorld! ͕ग़ྗ͞ΕΔ͜ ͱ͕Θ͔Γ·͢ɻ - ࠓ·Ͱͷιʔείʔυͷྫ͸ҎԼͷ

    gist ʹ ·ͱΊͯ͋Γ·͢ɻ - https://gist.github.com/ m3m0r7/226e20c8115caf4a9d43b291861 f978b  RubyVM ͷ࡞Γํ
  42. Appendix: CallInfoEntry ʹ͍ͭͯ  RubyVM ͷ࡞Γํ - RubyVM ্ͷ CallInfoEntry

    ͸࣮ߦ͞ΕΔϝιουͷϝλ৘ใΛऔಘ͢ΔͨΊ ʹඞཁͳ΋ͷͰ͢ɻ - ֨ೲ͞Ε͍ͯΔ৘ใ͸ʮϝιου໊ʯʮҾ਺ͷ਺ʯͳͲͰ͢ɻຊདྷ͸͜ΕΒΛ ༻͍ͯɼಈతʹϝιουΛ࣮ߦʢopt_send_without_block ໋ྩͷ࣮ߦʣΛ͞ ͤΔඞཁ͕͋Γ·͢ɻ - CallInfoEntry ͸࣍ͷϖʔδͷΑ͏ʹ࣮૷͢Δ͜ͱͰ puts Λࢦఆͤͣʹݺͼग़ ͢͜ͱ͕Ͱ͖·͢ɻ
  43. Appendix: CallInfoEntry ʹ͍ͭͯ  RubyVM ͷ࡞Γํ - ͜ΕͰ CallInfoEntry Λ࢖ͬͯϝιου໊Λࣗಈతʹղܾɼ·ͨҾ਺ͷ਺΋ղ

    ܾ͍ͯ͠ΔͷͰɼҾ਺͕૿͑ͨ৔߹Ͱ΋ϝιουͷݺͼग़͕͠Ͱ͖ΔΑ͏ʹͳ Γ·͢ɻ - ΋ͪΖΜ CallInfoEntry Ҏ֎ʹ΋ϩʔΧϧม਺ςʔϒϧʢϝιου͕ड͚औΔ Ҿ਺ͷ৘ใʣͰ͋ͬͨΓɼྫ֎ॲཧͰ͋ͬͨΓɼॏཁͳ৘ใ΋͋Γ·͢ɻ - HelloWorld! Λग़ྗͰ͖ͨઌɼ΋͋͠ͳ͕ͨ RubyVM ͷ࣮૷ʹڵຯΛ࣋ͪ࢝ ΊͨΒɼίʔυΛಡΜͰҙຯΛཧղ࣮͠૷ͯ͠Έͯ͸͍͔͕Ͱ͠ΐ͏͔ɻ
  44. Appendix: CallInfoEntry ʹ͍ͭͯ  RubyVM ͷ࡞Γํ - มߋՕॴ·ͰؚΊͨίʔυ͸ҎԼͷ gist Λࢀর͍ͯͩ͘͠͞

    - https://gist.github.com/m3m0r7/226e20c8115caf4a9d43b291861f978b? permalink_comment_id=4686761#gistcomment-4686761
  45. Appendix: RubyVM ͷ໋ྩηοτ਺ʹ͍ͭͯ  RubyVM ͷ࡞Γํ - RubyVM ͷ໋ྩηοτͷ਺͸ 100

    ݸ΄ͲͰ͢ʢ࣮ମ͸ 200 ݸ΄ͲͰ͕͢ɼ൒ ෼͸໋ྩΛτϨʔε͢ΔͨΊͷ໋ྩηοτͰ͢ʣɻͪͳΈʹ JVM ͸ 150 ݸ΄ ͲͰ͢ʢSE 13ʣɻ - ୯७ͳ HelloWorld! ͷग़ྗ΍ FizzBuzzɼΫΠοΫιʔτͷϨϕϧײͰ͋Ε ͹ɼશ࣮ͯ૷͠ͳͯ͘΋͍͔ͭ͘ͷ໋ྩηοτΛ࣮૷͢Ε͹࣮ߦ͢Δ͜ͱ͕Մ ೳʹͳΓ·͢ɻ
  46. Appendix: RubyVM ͷ໋ྩηοτ਺ʹ͍ͭͯ  RubyVM ͷ࡞Γํ - RubyVM ͕ఏڙ͍ͯ͠Δ໋ྩηοτ͸ҎԼΛࢀর͍ͯͩ͘͠͞ -

    https://github.com/ruby/ruby/blob/ruby_3_3/insns.def - PHP Ͱͷ࣮૷ྫ͸ҎԼΛࢀর͍ͯͩ͘͠͞ɻ - https://github.com/m3m0r7/rubyvm-on-php/tree/0.3.3.0/src/VM/Core/ Runtime/Executor/Insn/Processor
  47. Appendix: RubyVM ͷ໋ྩηοτ਺ʹ͍ͭͯ  RubyVM ͷ࡞Γํ - Ruby 3.3 ͔Β

    ҎԼͷ 6 ͭͷ໋ྩηοτ͕૿͑·ͨ͠ɻ - Ruby ͸໋ྩηοτ͕૿͑Δͱɼଞͷ໋ྩηοτͷ OpCode ͕ζϨΔΜͰ͢ΑͶ…ɻྫ͑͹ OPT_SEND_WITHOUT_BLOCK ͸ Ruby 3.2 Ͱ͸ 51 ͩͬͨͷ͕ Ruby 3.3 Ͱ͸ 53 ʹͳ͍ͬͯ·͢ɻ
 RubyVM ΛϚϧνόʔδϣϯରԠ͢Δ৔߹͸ɼ͜ͷ࢓༷Λߟྀ͢Δඞཁ͕͋Γ·͢Ͷɻ OpCode χʔϞχοΫ 33 SPLATKW 45 DEFINEDIVAR 58 OPT_NEWARRAY_SEND 135 TRACE_SPLATKW 147 TRACE_DEFINEDIVAR 160 TRACE_OPT_NEWARRAY_SEND
  48. Appendix: Ͳ͏΍ͬͯ Ruby ຊମΛࣸܦ͢Δ͔  RubyVM ͷ࡞Γํ - Ruby ຊମͷɼͱΓΘ͚

    VM Λ࣮૷͍ͯ͠ΔՕॴΛͲ͏΍ͬͯࣸܦ͢Δ͔Ͱ͢ ͕ɼجຊతʹ͸ compile.c ʢ https://github.com/ruby/ruby/blob/ruby_3_3/ compile.c ʣΛோΊΔͷ͕Ұ൪खͬऔΓૣ͍Ͱ͢ɻ - `ibf_load_*` ͱॻ͔Ε͍ͯΔؔ਺Λ௥͏ͱྑ͍Ͱ͢ɻ - ͱ͸͍͑ɼͲͷॱ൪Ͱݺͼग़͞ΕΔ͔ʹ͍ͭͯ͸ίʔυΛ௥͍͔ͬͯͳ͍ͱΘ ͔Βͳ͍ͷͰɼେ·͔ʹͲ͏΍ͬͯ௥͑͹͍͍͔࣍ϖʔδͰϑϩʔਤΛॻ͍ͯ ͓͖·͢ɻ
  49. Appendix: Ͳ͏΍ͬͯ Ruby ຊମΛࣸܦ͢Δ͔  RubyVM ͷ࡞Γํ rb_iseq_ibf_load ibf_load_setup ibf_load_iseq

    rb_ibf_load_iseq_compl ete ibf_load_iseq_each ibf_load_code ಡΈࠐΜͩ iseq Λ 
 ฦ͢ ibf_load_small_value ibf_load_object ibf_load_outer_variables ibf_load_param_opt_tabl e ibf_load_param_keywor d ibf_load_insns_info_bod y ibf_load_insns_info_posi tions ibf_load_local_table ibf_load_catch_table ibf_load_iseq_each Ͱݺ͹ΕΔؔ਺܈ ࠶ؼతʹ ibf_load_iseq ͕ݺͼग़͞ΕΔ compile.c ← Ruby ͷ RubyVM::InstructionSequence.load_from_binary ϝιουΛݺͼग़ͨ͠ࡍʹݺ͹ΕΔؔ਺ 
 (https://github.com/ruby/ruby/blob/ruby_3_3/iseq.c#L3870, https://github.com/ruby/ruby/blob/ruby_3_3/iseq.c#L4079) iseqw_s_load_from_bina ry iseq.c ibf_load_id
  50. Appendix: ϩʔΧϧม਺ͷׂ౰  RubyVM ͷ࡞Γํ - ఆٛͨ͠ϢʔβʔϥϯυͷϝιουΛ࣮૷͢Δࡍʹ᪴͘ϙΠϯτͷҰͭͱͯ͠ ϩʔΧϧม਺ͷׂ౰͕͋Γ·͢ɻࢲࣗ਎΋͍᪴ͯ·ͨ͠ɻ - ఆٛ͞ΕͨϝιουΛ࣮ߦ͢Δࡍʹɼ࣮ߦ࣌ʹʢελοΫʹϓογϡ͓ͯ͘͠

    ͷͰ͸ͳ͘ʣҾ਺Λ༧ΊϩʔΧϧςʔϒϧʹηοτ͓ͯ͘͠ඞཁ͕͋ΔͷͰ͢ ͕ɼͦͷηοτ͢ΔҾ਺ͷҐஔΛٻΊͳ͚Ε͹ͳΓ·ͤΜɻ - ιʔείʔυΛಡΉݶΓ EP (environment pointer) Λ༻ҙͯ͠ٻΊ͍ͯΔΑ͏ Ͱ͕͢ɼຊࢿྉͰ͸ EP Λ࢖Θͳ͍ͰٻΊ·͢ɻ
  51.  VM_ENV_DATA_SIZE ϝιου಺ͷม਺܈ ϝιουͷҾ਺ local table size: 4 0 1

    2 3 4 6 5 slot index var4 -> slot[3] var3 -> slot[4] var2 -> slot[5] var1 -> slot[6] call info argc: 2 - ྫͷ varN (N ͸ࣗવ਺, N>0) ͸ ʮVM_ENV_DATA_SIZE + local table size - (N - 1)ʯͰٻΊΒΕ·͢ɻͭ·Γ var1 ͸ʮVM_ENV_DATA_SIZE(3) + local table size(4) - N(1)ʯͰ slot[6] ʹ֨ೲ͞ΕΔ͜ͱ͕Θ͔Γ·͢ɻ - ϝιουʹ౉͢Ҿ਺͸ఆٛ͞ΕͨҾ਺ͷॱংͱ͸ٯͰ slot index ʹඥ෇͚Δඞཁ͕͋Γ·͢ - opcode ͷ [gs]etlocal(?:_WC[01]|) ΋͜Εʹैͬͯ஋ΛऔΔΑ͏ʹͳ͍ͬͯ·͢ - 3 ൪໨͔Βελʔτͳͷ͸ɼRubyVM ʹඞཁͳ৘ใΛຒΊࠐΜͰ͍ΔͨΊͬΆ͍ʢʁʣʢVM_ENV_DATA_INDEX_ME_CREF, VM_ENV_DATA_INDEX_SPECVAL, VM_ENV_DATA_INDEX_FLAGSʣ - Ҿ਺͕͋Δ৔߹͸ϝιουݺͼग़͠ͷલʹ༧Ί slot ʹ஋ΛೖΕͯϝιουݺͼग़͠Λߦ͏ඞཁ͕͋Γ·͢ɻྫͰ͸ var1 ͸ slot[6], var2 ͸ slot[5] ʹ༧Ί஋ΛೖΕ͓ͯ͘ඞཁ͕͋Γ·͢ɻ
 ͳ͓ɼvar3 ΍ var4 ͸಺෦ͷ໋ྩγʔέϯεʹ͓͍ͯ setlocal ͕ݺͼग़͞ΕΔͷͰɼ༧Ί஋ΛೖΕ͓ͯ͘ඞཁ͸͋Γ·ͤΜɻ
 (࣮૷ͷώϯτ: https://github.com/m3m0r7/rubyvm-on-php/blob/0.3.3.0/src/VM/Core/Runtime/Executor/CallBlockHelper.php#L121 )
  52. Appendix: ϩʔΧϧม਺ͷׂ౰  RubyVM ͷ࡞Γํ - ͞Βʹ RubyVM ͷϩʔΧϧม਺ʹ͸ level

    ͱ͍͏֓೦͕͋Γ·͢ɻlevel = 0 ͸ݱ ࡏͷ࣮ߦίϯςΩετΛද͢΋ͷͰɼlevel ͕ 1, 2, 3 ... ͱ૿͍͑ͯ͘͝ͱʹ level ͷ਺͚ͩલͷίϯςΩετʢRuby ຊମͷίʔυ্Ͱ͸ VM_ENV_PREV_EP ϚΫ ϩʹ֘౰ʣͷϩʔΧϧม਺Λࢀর͠·͢ʢ࣍ϖʔδਤࢀরʣɻ - ࣮ߦதͷίϯςΩετ͔Βݟͯɼ૬ରҐஔͱͯ͠ม਺ͷ͋ΔίϯςΩετͷ৔ॴ Λදͨ͠ͷ͕ level ͩͱࢥ͏ͱΘ͔Γ΍͍͔͢΋͠Ε·ͤΜɻ - ͦͷͨΊɼ࣮૷࣌ͷ஫ҙ఺ͱͯ͠ίϯςΩετ͸ḪΕΔΑ͏ʹ͓ͯ͘͠ඞཁ͕͋ Γ·͢ɻ
  53.  var3 ΁ͷ୅ೖ͸࣮ߦ࣌ͷίϯςΩετͳͷͰ 
 level ͸ 0 Ͱ setlocal_WC0 ͕૸Δ

    var3 ͕ఆٛ͞Ε͍ͯΔͷ͸ҰͭલͷίϯςΩετͳͷͰ 
 ࣮ߦதͷίϯςΩετ͔Βݟͯ level ͸ 1 Ͱ getlocal_WC1 ͕૸Δ var3 ͕ఆٛ͞Ε͍ͯΔͷ͸ҰͭલͷίϯςΩετͳͷͰ 
 ࣮ߦதͷίϯςΩετ͔Βݟͯ level ͸ 1 Ͱ setlocal_WC1 ͕૸Δ var1, var2 ͕ఆٛ͞Ε͍ͯΔͷ͸࣮ߦதͷίϯςΩετͳͷͰ level ͸ 0 Ͱ getlocal_WC0 ͕૸Δ ݺͼग़͠ʢ಺෦తʹ send/ opt_send_without_block ͳͲͷ opcode ͕ݺͼग़͞Εͱ͖ʣ͕͋Δͱ ࣮ߦίϯςΩετ͕มΘΔ