$30 off During Our Annual Pro Sale. View Details »

php-srcを読んでみよう / php-src codereading

tzmfreedom
September 24, 2022

php-srcを読んでみよう / php-src codereading

PHP Conference Japan 2022の発表資料です。
https://fortee.jp/phpcon-2022/proposal/1addf51d-6f72-4c96-9337-034ec6cc0643

tzmfreedom

September 24, 2022
Tweet

More Decks by tzmfreedom

Other Decks in Technology

Transcript

  1. גࣜձࣾϠϓϦా࣮੣ QIQTSDΛಡΜͰΈΑ͏

  2. ࣗݾ঺հ w ా࣮੣!U[N@GSFFEPN w גࣜձࣾϠϓϦͷαʔόʔαΠυΤϯδχΞ w 1)1ྺ͸ʙ೥͘Β͍ w $ݴޠྺ͸̍೥͘Β͍ʹॳ৺ऀ w

    1)1FS,BJHJͰ͸1)1Ͱ1)1Λ࣮૷ 
 1)1$POGFSFODFͰ͸ಠࣗϑϨʔϜϫʔΫΛվળ 
 1)1FS,BJHJͰ͸1)1Ͱ1)1ͷσόοΨʔΛ࣮૷
  3. None
  4. ͜ͷηογϣϯͰ͸ ϓϩάϥϛϯάݴޠͷιʔείʔυΛ ಡΈ͍ͨͱ͍͏ਓͷເΛ׎͑·͢

  5. ͜ͷηογϣϯͷ໨త w1)1ຊମͷιʔείʔυ QIQTSD ΛಡΉ্Ͱඞཁͳ஌ ࣝ΍ಡΈํΛͬ͟ͱ঺հ wQIQTSDΛશ͘ಡΜͩ͜ͱ͕ͳ͘ɺ$ݴޠ΋ͦΜͳʹ஌ Βͳ͍ਓ͕ಡΊͦ͏ͳؾ࣋ͪʹͳΔ͜ͱ͕໨ඪ w͜ΕΛ͖͔͚ͬʹQIQTSDΛಡΉحಛͳਓΛ૿΍͢ 
 ϓϩάϥϛϯάݴޠͷιʔείʔυΛ͍͔ͭಡΜͰΈͨ

    ͍ɺͱࢥ͍ͬͯΔਓͷಡΉ͖͔͚ͬʹͳͬͯ͘ΕΔͱخ ͍͠Ͱ͢
  6. ͜ͷηογϣϯͰ࿩͢͜ͱ w QIQTSDͷσόοάͷํ๏ w σόοάϏϧυͷํ๏ w (%#ͷΠϯετʔϧ w QIQTSDΛಡΉ্Ͱඞཁͳ1)1ͱ$ݴޠͷ஌ࣝ w

    FDIPͷίʔυΛಡΜͰΈΑ͏ w 1)1Λվ଄ͯ͠ΈΑ͏ w ˞ಡΉ͜ͱʹϑΥʔΧε͍ͯ͠·͢
  7. QIQTSDͷσόοάͷํ๏

  8. QIQTSDͷσόοά͕Ͱ͖ΔΑ͏ʹ͢Δ w ίʔυΛಡΉ͚ͩͰ׬શʹཧղ͢Δ͜ͱ͸೉͍͠ w σόοά͢Δ͜ͱͰɺͦͷͱ͖ͷม਺ͷ஋΍ݺͼग़͠ݩʢελ οΫτϨʔεʣ͕֬ೝͰ͖ͯਖ਼͍͠ཧղ͕Ͱ͖Δ w σόοά͢Δʹ͸1)1ͷσόοάϏϧυ͕ඞཁ w 1)1͸$ݴޠͰ࣮૷͞Ε͍ͯΔͷͰ(%#ͰσόοάͰ͖Δ

    w (%#(/6%FCVHHFS$6*56*ͳσόοΨʔ
  9. 1)1ͷσόοάϏϧυͷํ๏ Ϗϧυ͢ΔͱTBQJDMJQIQʹ1)1ͷ$-*͕࡞੒͞ΕΔ $ git clone git@github.com:php/php-src.git $ cd php-src $

    ./buildconf $ ./configure --enable-opcache --enable-debug $ make -j4 $ sapi/cli/php test.php
  10. (%#ΛΠϯετʔϧNBD04ͷ৔߹ w ίʔυॺ໊Λ͠ͳ͍ͱ࢖͑ͳ͍ͷͰΩʔνΣʔϯΞΫηεͰূ ໌ॻΛ࡞੒ͯ͠YNMϑΝΠϧ࡞੒ͯ͠ίʔυॺ໊͢Δ w ৄࡉ͸ൃදࢿྉͷ"QQFOEJYʹهࡌ $ brew install gdb

    $ codesign --entitlements gdb.xml -fs gdb $(which gdb)
  11. (6*ͳσόοάͷઃఆ w ׽͸໧ͬͯ(%#Λ௚઀࢖ͬͨ56*σόοάͰ΋ྑ͍͕ w (6*ϕʔεͷσόοά͕Ͱ͖Δͱίʔυͷཧղ͕ḿΔ w 74$PEFͰͷ(6*σόοάͷઃఆ͸͜Ε͚ͩˣ w $$ ͷϓϥάΠϯΛΠϯετʔϧ

    w MBVODIKTPOΛઃఆ w ৄࡉ͸ൃදࢿྉͷ"QQFOEJYʹهࡌ
  12. (6*ͷσόοάྫ ม਺Λ֬ೝ͢Δͱ͜Ζ ίʔϧελοΫ εςοϓ࣮ߦͷૢ࡞

  13. σόοάίϯιʔϧͰ56*σόοά͢Δ͜ͱ΋Մೳ ͜͜ͰίϚϯυΛ࣮ߦ

  14. HECJOJUͰ͞Βʹศརʹσόοά͢Δ w (%#ʹ͸HECJOJUͱ͍͏(%#࣮ߦ࣌ʹಡ·ΕΔϑΝΠϧ͕͋Δ w QIQTSD௚Լʹ΋HECJOJU͕͋ΓɺQIQTSDΛσόοά͢Δͨ Ίͷศརؔ਺͕༻ҙ͞Ε͍ͯΔ QSJOU@DWT $7ʢม਺ʣͷҰཡΛऔಘ QSJOU[W [WBMΛಡΈ΍͘͢දࣔ

    QSJOU@[TUS [TUSJOHΛಡΈ΍͘͢දࣔ HECJOJUʹఆٛ͞Ε͍ͯΔؔ਺ͷྫ
  15. Α͠ɺ1)1ͷίʔυΛಡΉͧʂ

  16. ͦͷલʹ$ݴޠͷجૅ஌ࣝ

  17. QIQTSDΛಡΉલͷ$ݴޠͷجૅ஌ࣝ w جຊతʹ͸งғؾͰಡΜͰ͍͚͹0, w ϚΫϩͱϝϞϦ͚ͩ஫ҙ͕ඞཁ

  18. ϚΫϩ w ϏϧυલʹߦΘΕΔจࣈྻஔ׵ w จࣈྻஔ׵͕Ώ͑ԿͰ΋Ͱ͖Δɻ$ݴޠͷߏจແࢹͯ͘͠Δɻ w QIQTSDΛಡΉͱ͖͸େྔͷϚΫϩͱ޲͖߹͏ඞཁ͕͋Δ #define PHP_VERSION "8.2.0-dev"

    #define PHP_VERSION_ID 80200
  19. ࣮ࡍͷίʔυྫ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *z; SAVE_OPLINE();

    z = RT_CONSTANT(opline, opline->op1);
  20. ࣮ࡍͷίʔυྫ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *z; SAVE_OPLINE();

    z = RT_CONSTANT(opline, opline->op1); ͑ɺͳΜ͔ηϛίϩϯແ͍Μ͚ͩͲʜʂ ͑ɺܕ͕ϚΫϩʹͳ͍ͬͯΔʜʁ ͑ɺҾ਺Ͳ͏ͳͬͯΜͷʜʂʁ PQMJOF͍ͬͯ͏ม਺ɺͲ͜ʹ΋ఆٛ͞Ε͍ͯͳ͍ͷ͕ͩʜʁʁ
  21. ϚΫϩ͸͜Μͳײ͡Ͱఆٛ͞Ε͍ͯΔ # define ZEND_OPCODE_HANDLER_RET int # define ZEND_FASTCALL # define

    ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data # define USE_OPLINE const zend_op *opline = EX(opline); #define EX(element) ((execute_data)->element)
  22. ల։͢Δͱ͜Μͳײ͡ static int ZEND_ECHO_SPEC_CONST_HANDLER(zend_execute_data *execute_data) { const zend_op *opline =

    ((execute_data)->opline); zval *z; static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *z;
  23. ͜ΜͳϚΫϩ΋͋Δ ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { //… } ZEND_HASH_FOREACH_END(); do { for(...)

    { { //... } } } while(0) w ։࢝ͷϚΫϩͱऴྃͷϚΫϩͰରʹͳ Δɻ w ͪͳΈʹEPʙXIJMF  ΛೖΕ͍ͯΔͷ ͸JGจͳͲͰෳ਺จͷల։Λͨ͠ͱ͖ʹ ҙਤͨ͠ڍಈʹ͢ΔͨΊ
  24. ϝϞϦ഑ஔ w ܕఆٛΛݟΔ͚ͩͰ͸ίʔυ͕ಡΊͳ͍ʢʂʁʣ w $ݴޠ͸ϝϞϦ؅ཧΛॊೈʹߦ͑Δ w ܕఆ͚ٛͩͰ͸ͳ͘ɺϝϞϦׂΓ౰ͯɾ഑ஔΛཧղ͢Δඞཁ ͕͋Δ

  25. ίʔϧϑϨʔϜͷϝϞϦ഑ஔྫ w [FOE@FYFDVUF@EBUBม਺ [WBM ʜͱ͍͏ײ͡Ͱ഑ஔ͞Εͯ ͍Δ w ϝϞϦΛಈతʹ֬อͯ͠[FOE@FYFDVUF@EBUBͱ[WBMͷྖҬΛܾΊͯ ഑ஔ 


    [FOE@FYFDVUF@EBUBͷఆ͚ٛͩͰ͸ϝϞϦ഑ஔ͸Θ͔Βͳ͍ [WBM FYFDVUF@EBUB ࣮ߦதͷؔ਺΍0QDPEF౳ΛؚΉߏ଄ମ [WBM ൪໨ͷม਺ ൪໨ͷม਺
  26. ม਺ͷߏ଄ମΛऔಘ͢Δྫ ((zval*)(((char*)(execute_data)) + ((int)(n)))) w FYFDVUF@EBUBͷϙΠϯλʢઌ಄ͷΞυϨεʣ͔ΒOόΠτઌ ʹ͋ΔΞυϨε͔Β[WBMߏ଄ମΛऔಘ͍ͯ͠Δɻ

  27. Α͠ɺ1)1ͷίʔυΛಡΉͧʂ

  28. ͦͷલʹ1)1ͷجૅ஌ࣝ

  29. 4"1* w 4FSWFS"1* w ༷ʑͳ8FCαʔόʔͰ1)1Λಈ͔ͨ͢Ίͷ"1* w 1)1ͷίΞʹ;FOE&OHJOFΛ࢖͏ͨΊͷΠϯλʔϑΣʔε w $-* 1)1%#(

    NPE@QIQ QIQGQN 'BTU$(* ʜ
  30. ;FOE&OHJOF w 1)1ͷεΫϦϓτΛ࣮ߦ͢ΔΤϯδϯ w $-*΋NPE@QIQ΋QIQGQN΋࠷ऴతʹ;FOE&OHJOFΛݺΜͰ ͍Δ

  31. 4"1*;FOE&OHJOFͷ֓ཁਤ BQBDIF NPE@QIQ 4"1* ;FOE&OHJOF )551 ϦΫΤετ $-* 4"1* ;FOE&OHJOF

    ίϚϯυ ࣮ߦ OHJOY QIQGQN 4"1* ;FOE&OHJOF )551 ϦΫΤετ
  32. $-*ͷFDIPͷελοΫτϨʔε NBJO TBQJDMJQIQ@DMJD EP@DMJ TBQJDMJQIQ@DMJD QIQ@FYFDVUF@TDSJQU NBJONBJOD [FOE@FYFDVUF@TDSJQUT ;FOE[FOED [FOE@FYFDVUF

    ;FOE[FOE@WN@FYFDVUFI FYFDVUF@FY ;FOE[FOE@WN@FYFDVUFI ;&/%@&$)0@41&$@$0/45@)"/%-&3 ;FOE[FOE@WN@FYFDVUFI 4"1* ;FOE&OHJOF
  33. QIQGQNͷFDIPͷελοΫτϨʔε NBJO TBQJGQNGQNGQN@NBJOD QIQ@FYFDVUF@TDSJQU NBJONBJOD [FOE@FYFDVUF@TDSJQUT ;FOE[FOED [FOE@FYFDVUF ;FOE[FOE@WN@FYFDVUFI FYFDVUF@FY

    ;FOE[FOE@WN@FYFDVUFI ;&/%@&$)0@41&$@$0/45@)"/%-&3 ;FOE[FOE@WN@FYFDVUFI 4"1* ;FOE&OHJOF
  34. 1)1ͷॲཧͷྲྀΕ

  35. 1)1ͷॲཧͷྲྀΕ  4"1*͔Βىಈ  εΫϦϓτΛղੳͯ͠"45Խ  "45͔Β0QDPEFʢόΠτίʔυʣΛੜ੒  0QDPEFΛ࣮ߦ

  36. 1)1εΫϦϓτΛղੳͯ͠"45Խ w "45"CTUSBDU4ZOUBY5SFF w ͍ΘΏΔࣈ۟ղੳɺߏจղੳ w ࡶʹݴ͏ͱεΫϦϓτΛߏ଄ମʹ͢Δॲཧ [FOE@BTU "45@45.5@-*45 [FOE@BTU

    "45@"44*(/ [FOE@BTU "45@&$)0  QIQ J FDIPJ
  37. ࣈ۟ղੳɾߏจղੳͷίʔυ͸ࣗಈੜ੒͞ΕΔ start: top_statement_list { CG(ast) = $1; (void) zendnerrs; }

    ; echo_expr_list: echo_expr_list ',' echo_expr { $$ = zend_ast_list_add($1, $3); } | echo_expr { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } ; echo_expr: expr { $$ = zend_ast_create(ZEND_AST_ECHO, $1); } ; w ;FOE[FOE@MBOHVBHFZ΍;FOE[FOE@MBOHVBHF@TDBOOFSM͔Β 
 ύʔαʔͷίʔυ͕ࣗಈੜ੒͞ΕΔ
  38. "45͔Β0QDPEFΛੜ੒ [FOE@BTU "45@45.5@-*45 [FOE@BTU "45@"44*(/ [FOE@BTU "45@&$)0 "44*(/ &$)0 $7

    JOU  TUSJOH lIPHFz  PQDPEF PQ PQ   SFTVMU w ωετͨ͠ଟ֊૚ͷߏ଄ମ͔Β̍֊૚ͷߏ଄ମͷ഑ྻʹม׵
  39. ม׵͍ͯ͠Δॲཧͷྫ static void zend_compile_echo(zend_ast *ast) /* {{{ */ { zend_op

    *opline; zend_ast *expr_ast = ast->child[0]; znode expr_node; zend_compile_expr(&expr_node, expr_ast); opline = zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL); opline->extended_value = 0; } &$)0ͷ0QDPEFΛ࡞੒ w ;FOE[FOE@DPNQJMFDʹ"45͔Β0QDPEFΛੜ੒͢Δؔ਺͕͋Δ
  40. 0QDPEFͷ֬ೝํ๏ w 0QDBDIFͷΦϓγϣϯΛࢦఆ͢Δͱ0QDPEFΛμϯϓͰ͖Δ $ sapi/cli/php -dopcache.opt_debug_level=0x10000 test.php $_main: ; (lines=3,

    args=0, vars=1, tmps=1) ; (before optimizer) ; /Users/nuser/phpconf2022/php-src/test.php:1-5 ; return [] RANGE[0..0] 0000 ASSIGN CV0($i) int(1) 0001 ECHO CV0($i) 0002 RETURN int(1)
  41. 0QDPEFͷ࣮ߦ w 0QDPEFͱΦϖϨʔλͭɺ ݁Ռͷ֨ೲઌ͕ೖ͍ͬͯΔ w 0QDPEFΛ࣮ߦ͢Δϋϯυϥ ʔʢؔ਺ϙΠϯλʣ΋ඥ෇͍ ͍ͯΔ struct _zend_op

    { const void *handler; znode_op op1; znode_op op2; znode_op result; uint32_t extended_value; uint32_t lineno; zend_uchar opcode; zend_uchar op1_type; zend_uchar op2_type; zend_uchar result_type; };
  42. 0QDPEFΛ࣮ߦ͍ͯ͠Δίʔυ while (1) { int ret; if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE-

    >handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0)) { if (EXPECTED(ret > 0)) { execute_data = EG(current_execute_data); ZEND_VM_LOOP_INTERRUPT_CHECK(); } else { return; } } }
  43. Α͠ɺ1)1ͷίʔυΛಡΉͧʂʢ̏ճ໨

  44. FDIPΛಡΜͰΈΑ͏

  45. FDIP͕Ͳ͏ಈ͍͍ͯΔͷ͔ΛݟͯΈΑ͏ w "45Λ֬ೝ͢Δ w 0QDPEFΛ֬ೝ͢Δ w ϋϯυϥʔͷॲཧΛ֬ೝ͢Δ

  46. "45Λ֬ೝ͢Δ w ద౰ͳͱ͜ΖʹϒϨʔΫϙΠϯτΛషͬͯ$( BTU Λσόο ά͢Δ w ͷ͸େมͳͷͰOJLJDQIQBTUΛ࢖ͬͯશମͷߏ଄Λ೺Ѳ͢Δ $ pecl

    install ast var_dump(ast\parse_code(‘<?php echo "hoge";', $version=90));
  47. class ast\Node#1 (4) { public $kind => int(132) public $flags

    => int(0) public $lineno => int(1) public $children => array(1) { [0] => class ast\Node#2 (4) { public $kind => int(283) public $flags => int(0) public $lineno => int(1) public $children => array(1) { 'expr' => string(4) "hoge" } } } } w  ;&/%@"45@45.5@-*45 w  ;&/%@"45@&$)0 [FOE@BTU "45@45.5@-*45 [FOE@BTU "45@&$)0 [FOE@BTU@[WBM 
 TUSJOH
  48. 0QDPEFΛ֬ೝ͢Δ w &$)0ͱ͍͏0QDPEFΛ֬ೝͰ͖Δ 
 &$)0ΛϋϯυϦϯά͢Δؔ਺͕͋Δ͸ͣ w ˞3&563/JOU  ͸Ұ୴εϧʔͰ0, 0000

    ECHO string(“hoge”) 0001 RETURN int(1)
  49. ϋϯυϥʔΛ֬ೝ͢Δ w ;FOE[FOE@WN@FYFDVUFIʹఆٛ͞Ε͍ͯΔ w ;&/%@\0QDPEF^@41&$@\Ҿ਺ͷछผ^@)"/%-&3ͱ͍͏໊લʹͳ͍ͬͯΔ w &$)0ͷϋϯυϥʔͰ͸[FOE@XSJUF ؔ਺͕ݺ͹Ε͍ͯΔ static ZEND_OPCODE_HANDLER_RET

    ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { // …লུ… if (ZSTR_LEN(str) != 0) { zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
  50. [FOE@XSJUF w ؔ਺ϙΠϯλ w 4"1*ʹΑͬͯηοτ͞ΕΔؔ਺͕มΘΔ w $-*͸ඪ४ग़ྗʹॻ͖ࠐΉ w NPE@QIQ͸BQBDIFͷؔ਺ܦ༝Ͱ)551ϨεϙϯεΛฦ͢ extern

    ZEND_API zend_write_func_t zend_write; typedef size_t (*zend_write_func_t)(const char *str, size_t str_length);
  51. 1)1Λվ଄ͯ͠ΈΑ͏

  52. վ଄ֶͯ͠Ϳ1)1 w ԿΛFDIPͯ͠΋ʮ1)1࠷ߴʂʂʯ͕ग़Δ1)1ʹ͢Δ $ sapi/cli/php test.php PHP࠷ߴ!!PHP࠷ߴ!!PHP࠷ߴ!!PHP࠷ߴ!! <?php echo "hoge";

    echo "hoge"; echo "hoge"; echo "hoge"; $ sapi/cli/php test.php hogehogehogehoge
  53. վ଄ͷ΍Γํ w 0QDPEFͷॲཧͷৼΔ෣͍Λม͑Ε͹0, w ;&/%@&$)0@41&$@$0/45@)"/%-&3ͳͲ w ॻ͖׵͑ͨ͋ͱ͸࠶౓NBLFͯ͠Ϗϧυ - zend_write(ZSTR_VAL(str), ZSTR_LEN(str));

    + char *str = “PHP࠷ߴ!!”; + zend_write(str, strlen(str));
  54. None
  55. QIQTSDಡΊͦ͏ʹͳΓ·ͨ͠ΑͶʁ

  56. ·ͱΊ w 1)1ͷσόοάͷํ๏͔ΒಡΉํ๏·Ͱͬ͟ͱ঺հ͠·ͨ͠ w ϓϩάϥϛϯάݴޠͷίʔυΛಡΉͷ͸ɺ΍Γํ͑͞஌ͬͯ ͍Ε͹ͦ͏೉͗͢͠Δ΋ͷͰ΋ͳ͘୭Ͱ΋Ͱ͖·͢ w ීஈԿؾͳ͘࢖͍ͬͯΔ1)1͕Ͳ͏΍ͬͯಈ͍͍ͯΔͷ͔͕ Θ͔Δͱ໘ന͍Ͱ͢ w

    ஌Βͳ͍࢓༷΋ग़͖ͯͨΓɺݴޠ࢓༷ΛΑΓཧղͰ͖·͢ w ΤϯδχΞͷᅂΈͱ͍͔͕ͯ͠Ͱ͠ΐ͏͔ʁ
  57. &OKPZ$PEF3FBEJOHʂʂ

  58. "QQFOEJY

  59. ಡΉ্Ͱࢀߟʹͳͬͨهࣄ w ϨϯδΦϖϨʔλͷ࣮૷ w IUUQTQIQJOUFSOBMTOFUBSUJDMFT JNQMFNFOUJOH@B@SBOHF@PQFSBUPS@JOUP@QIQ w ৽͍͠ԋࢉࢠΛ࣮૷͍ͯ͘͠QIQTSDνϡʔτϦΞϧ w ࣈ۟ղੳɾߏจղੳʙ0QDPEFੜ੒ɾ0QDPEF࣮ߦ·ͰܦݧͰ͖Δ

    w 1)1*OUFSOBMT#PPL w IUUQTXXXQIQJOUFSOBMTCPPLDPN w /JLJDେઌੜͷϒϩά w IUUQTXXXOQPQPWDPN
  60. (%#ͷίʔυॺ໊  dHECJOJUͷઃఆ  ΩʔνΣʔϯΞΫηεͰίʔυॺ໊༻ͷূ໌ॻΛ࡞੒  ίʔυॺ໊ʹඞཁͳ9.-ϑΝΠϧΛ࡞੒  ίʔυॺ໊Λ࣮ߦ ৄࡉ͸ҎԼͷهࣄ͕Θ͔Γ΍͍͢Ͱ͢ʂ🙏

    w IUUQTUBNBLJJJIBUFOBCMPHDPNFOUSZ w IUUQTCMPHTZNEPOJOGPQPTUT
  61. 74$PEFͷ$$ ͷϓϥάΠϯ w IUUQTDPEFWJTVBMTUVEJPDPNEPDTMBOHVBHFTDQQ w IUUQTDPEFWJTVBMTUVEJPDPNEPDTDQQDQQEFCVH