PHP NorthWest 'All The Jumps' talk

This commit is contained in:
Derick Rethans
2016-09-30 12:14:57 +01:00
parent 23e62764b7
commit d993def5fa
50 changed files with 1218 additions and 2 deletions

116
jump-phpnw16.xml Normal file
View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<presentation css="10gen-strict.css">
<topic>PHP</topic>
<title>It's All About the Jumps</title>
<event>PHP North West 2016</event>
<location>Manchester, UK</location>
<date>October 1st, 2016</date>
<speaker>Derick Rethans</speaker>
<email>derick@php.net</email>
<twitter>derickr</twitter>
<joindin>https://joind.in/18836</joindin>
<slide>slides/mongodb/title.xml</slide>
<slide>slides/mongodb/me.xml</slide>
<slide>slides/internals/title-agenda.xml</slide>
<slide>slides/internals/title-stages.xml</slide>
<!-- INTRODUCTION
Compile stages:
Parse script
Create AST
Convert to opcodes
Run the code
Opcache for caching
-->
<slide>slides/internals/stages.xml</slide>
<!-- STAGES
Parse
- Show parser rules
- Show "compiler" rules
-->
<slide>slides/internals/title-parsing.xml</slide>
<slide>slides/internals/parse-state-machine.xml</slide>
<slide>slides/internals/parse-tokenization.xml</slide>
<slide>slides/internals/scanner.xml</slide>
<slide>slides/internals/scanner-rules.xml</slide>
<slide>slides/internals/ast.xml</slide>
<slide>slides/internals/ast1.xml</slide>
<slide>slides/internals/scanner-ast.xml</slide>
<slide>slides/internals/scanner-ast2.xml</slide>
<slide>slides/internals/bytecode0.xml</slide>
<slide>slides/internals/bytecode½.xml</slide>
<slide>slides/internals/bytecode1.xml</slide>
<slide>slides/internals/jumps.xml</slide>
<!--
AST
- Show AST for various control structures
Opcodes
- Show AST for the same control structures
-->
<slide>slides/internals/jumps-if.xml</slide>
<slide>slides/internals/jumps-if-else.xml</slide>
<slide>slides/internals/rings.xml</slide>
<slide>slides/internals/jumps-for.xml</slide>
<slide>slides/internals/jumps-for-rewritten.xml</slide>
<slide>slides/internals/jumps-while.xml</slide>
<slide>slides/internals/jumps-do-while.xml</slide>
<slide>slides/internals/jumps-foreach.xml</slide>
<slide>slides/internals/jumps-complex.xml</slide>
<slide>slides/internals/loops.xml</slide>
<slide>slides/internals/jumps-complex-dot.xml</slide>
<!--
Try/Catch nonsense
- FASTCALL/FASTRET
-->
<slide>slides/internals/catch.xml</slide>
<slide>slides/internals/jumps-try-catch.xml</slide>
<!--
Dead code analysis
- Show how Xdebug does it through VLD
-->
<slide>slides/internals/deadcode.xml</slide>
<slide>slides/internals/deadcode-vld.xml</slide>
<!--
Path analysis
- Branch and Path
-->
<slide>slides/internals/branches.xml</slide>
<slide>slides/xdebug/vld-path-2-paths.xml</slide>
<slide>slides/xdebug/vld-path-4-code.xml</slide>
<slide>slides/xdebug/vld-path-4-output.xml</slide>
<slide>slides/xdebug/vld-path-3-code.xml</slide>
<slide>slides/xdebug/vld-path-3-output.xml</slide>
<slide>slides/xdebug/vld-path-3-paths.xml</slide>
<!-- Conclusion
Code -> Tokens -> AST -> opode
Transformation of control structures
Useful implementations
-->
<slide>slides/internals/recap.xml</slide>
<slide>slides/internals/recap-content.xml</slide>
<slide>slides/mongodb/questions.xml</slide>
<slide>slides/mongodb/resources.xml</slide>
</presentation>

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB

4
slides/internals/ast.xml Normal file
View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Abstract Syntax Tree</title>
<image align="center" filename="abstract-tree.jpg" attr=""/>
</slide>

12
slides/internals/ast1.xml Normal file
View File

@@ -0,0 +1,12 @@
<slide>
<title>Abstract Syntax Tree</title>
<list>
<bullet>An AST describes the structure of the parser script</bullet>
<bullet>Each node is a language construct</bullet>
<bullet>Nested structures are represented through a tree</bullet>
<bullet>Not all the original information from the original source code is kept</bullet>
<bullet>The *php-ast* extension on Nikita Popov's (nikic) GitHub account can visualize them</bullet>
<bullet>Optimisations are possible by modifications of the tree</bullet>
</list>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Branch Analysis</title>
<image align="center" filename="branches.jpg" attr="Sergey Kochkarev - https://www.flickr.com/photos/skochkar/24747666840/ - Public Domain"/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Byte Code</title>
<image align="center" filename="bytecode.jpg" attr=""/>
</slide>

View File

@@ -0,0 +1,33 @@
<slide>
<title>AST is converted to bytecode</title>
<example inline="1">
1: AST_METHOD
flags: MODIFIER_PUBLIC (256)
name: |00dd00|__construct|
params: AST_PARAM_LIST
0: AST_PARAM
name: |0000dd|"name"|
stmts: AST_STMT_LIST
0: |dd00dd|AST_ASSIGN|
var: |00dddd|AST_PROP|
expr: AST_VAR
name: |00dddd|"this"|
prop: |00dddd|"name"|
expr: AST_VAR
name: |0000dd|"name"|
</example>
<br/>
<example inline="1">
compiled vars: |0000dd|!0 = $name|
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8 0 E > EXT_NOP
1 RECV |0000dd|!0|
10 2 EXT_STMT
3 |dd00dd|ASSIGN||00dddd|_OBJ| |00dddd|'name'|
4 |dd00dd|OP_DATA| |0000dd|!0|
11 5 EXT_STMT
6 > RETURN null
</example>
</slide>

View File

@@ -0,0 +1,12 @@
<slide>
<title>Byte Code</title>
<list>
<bullet>In PHP also called Opcodes</bullet>
<bullet>Each function, method, or main body is represented by an Oparray</bullet>
<bullet>Each Oparray contains Opcodes with instructions for the Zend Engine</bullet>
<bullet>The Zend Engine executes each opcode in turn</bullet>
<bullet>Very similar to Assembler instructions</bullet>
<bullet>You can visualize them with the PECL *vld* extension</bullet>
</list>
</slide>

BIN
slides/internals/catch.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Exceptions (Try/Catch)</title>
<image align="center" filename="catch.jpg" attr="Soggydan Benenovitch (https://www.flickr.com/photos/38518750@N00/4858510277)"/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,28 @@
<slide>
<title>Dead Code</title>
<image align="right" filename="deadcode.png"/>
<example inline="1">&amp;lt;?php
if ( $a &amp;lt; 42 ) {
echo "fourty";
return;
*echo "two";*
}
</example>
<example inline="1">
line #* E I O op return operands
2 0 E > IS_SMALLER ~1 !0, 42
1 > JMPZ ~1, ->5
3 2 > ECHO 'fourty'
4 3 > RETURN null
5 *4\* ECHO 'two'*
5 > > RETURN 1
</example>
<list>
<bullet>Follow all branches</bullet>
<bullet>Find unreached opcodes</bullet>
</list>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Dead Code</title>
<image align="center" filename="rosetta.jpg" attr="Cristian Bortes - https://www.flickr.com/photos/bortescristian/2931856207 - CC-BY"/>
</slide>

View File

@@ -0,0 +1,36 @@
<slide>
<title>Complex Loops</title>
<image align="right" filename="complex-dot.png"/>
<example inline="1">&amp;lt;?php
$a = [ 2.7, 4.9 ];
|dd0000|foreach ( $a as $key => $value )| {
|00dd00|if ( $value &amp;lt; 3 ) {|
echo $key;
} else {
|0000dd|if ( $key > 0 ) {|
echo $value;
}
}
}
</example>
<example inline="1">
line #* E I O op return operands
2 0 E > ASSIGN !0, &amp;lt;array>
3 1 > |dd0000|FE_RESET_R $4 !0, ->12|
2 > > |dd0000|FE_FETCH_R ~5 $4, !1, ->12|
3 > |dd0000|ASSIGN !2, ~5|
4 4 |00dd00|IS_SMALLER ~7 !1, 3|
5 > |00dd00|JMPZ ~7, ->8|
5 6 > ECHO !2
7 > |00dd00|JMP ->11|
7 8 > |0000dd|IS_SMALLER ~8 0, !2|
9 > |0000dd|JMPZ ~8, ->11|
8 10 > ECHO !1
11 > > |dd0000|JMP ->2|
12 > |dd0000|FE_FREE $4|
13 > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,33 @@
<slide>
<title>Complex Loops</title>
<example inline="1">&amp;lt;?php
$a = [ 2.7, 4.9 ];
foreach ( $a as $key => $value ) {
if ( $value &amp;lt; 3 ) {
echo $key;
} else {
if ( $key > 0 ) {
echo $value;
}
}
}
</example>
<example inline="1">line #* E I O op fetch ext return operands
2 0 E > ASSIGN !0, &amp;lt;array>
3 1 > FE_RESET_R $4 !0, ->12
2 > > FE_FETCH_R ~5 $4, !1, ->12
3 > ASSIGN !2, ~5
4 4 IS_SMALLER ~7 !1, 3
5 > JMPZ ~7, ->8
5 6 > ECHO !2
7 > JMP ->11
7 8 > IS_SMALLER ~8 0, !2
9 > JMPZ ~8, ->11
8 10 > ECHO !1
11 > > JMP ->2
12 > FE_FREE $4
13 > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,22 @@
<slide>
<title>DO .. WHILE</title>
<example inline="1">&amp;lt;?php
|dd0000|$i = 10;|
do {
|0000dd|echo $i;|
} while ( |00dd00|--$i| );
</example>
<example inline="1">compiled vars: !0 = $i
line #* E I O op fetch ext return operands
2 0 E > EXT_STMT
1 |dd0000|ASSIGN !0, 10|
3 2 NOP
4 3 > EXT_STMT
4 |0000dd|ECHO !0|
5 5 |00dd00|PRE_DEC $2 !0|
6 > |00dd00|JMPNZ $2, ->3|
7 > > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,36 @@
<slide>
<title>FOR (rewritten)</title>
<example inline="1">
for ( |dd0000|$i = 0|; |00dd00|$i &amp;lt; 42|; |0000dd|++$i| ) {
|dd00dd|echo $i;|
}
</example>
<example inline="1">
|dd0000|$i = 0;|
goto COND;
STMT:
|dd00dd|echo $i;|
|0000dd|++$i;|
COND:
|00dd00|$_ = $i &amp;lt; 42;|
|00dd00|if ( ! $_ ) {|
|00dd00|goto STMT;|
|00dd00|}|
</example>
<example inline="1">compiled vars: !0 = $i
line #* E I O op fetch ext return operands
2 0 E > EXT_STMT
1 |dd0000|ASSIGN !0, 0|
2 > |dd0000|JMP ->6|
4 3 > |dd00dd|EXT_STMT |
4 |dd00dd|ECHO !0|
2 5 |0000dd|PRE_INC !0|
6 > |00dd00|IS_SMALLER ~3 !0, 42|
7 |00dd00|EXT_STMT |
8 > |00dd00|JMPNZ ~3, ->3|
9 > > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,50 @@
<slide>
<title>FOR</title>
<table class="two">
<tr>
<td>
<example inline="1">
&amp;lt;?php
for ( |dd0000|$i = 0|; |00dd00|$i &amp;lt; 42|; |0000dd|++$i| ) {
|dd00dd|echo $i;|
}
</example>
</td>
<td>
<example inline="1">
|dd0000|init: AST_EXPR_LIST|
0: AST_ASSIGN
var: AST_VAR
name: "i"
expr: 0
|00dd00|cond: AST_EXPR_LIST|
0: AST_BINARY_OP
flags: BINARY_IS_SMALLER (19)
left: AST_VAR
name: "i"
right: 42
|0000dd|loop: AST_EXPR_LIST|
0: AST_PRE_INC
var: AST_VAR
name: "i"
|dd00dd|stmts: …|</example>
</td>
</tr></table>
<example inline="1">compiled vars: !0 = $i
line #* E I O op fetch ext return operands
2 0 E > EXT_STMT
1 |dd0000|ASSIGN !0, 0|
2 > |dd0000|JMP ->6|
4 3 > |dd00dd|EXT_STMT |
4 |dd00dd|ECHO !0|
2 5 |0000dd|PRE_INC !0|
6 > |00dd00|IS_SMALLER ~3 !0, 42|
7 |00dd00|EXT_STMT |
8 > |00dd00|JMPNZ ~3, ->3|
9 > > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,28 @@
<slide>
<title>FOREACH</title>
<example inline="1">&amp;lt;?php
|dd0000|$a = [ 2.7, 4.9 ];|
|00dd00|foreach ( $a as $key => $value )| {
echo $key, $value;
}
</example>
<example inline="1">
compiled vars: !0 = $a, !1 = $value, !2 = $key
line #* E I O op fetch ext return operands
2 0 E > EXT_STMT
1 |dd0000|ASSIGN !0, &amp;lt;array>|
3 2 EXT_STMT
3 > |00dd00|FE_RESET_R $4 !0,| |dd00dd|->11|
*4* > > |00dd00|FE_FETCH_R ~5 $4, !1,| |dd00dd|->11|
5 > |00dd00|ASSIGN !2, ~5|
4 6 EXT_STMT
7 ECHO !2
8 EXT_STMT
9 ECHO !1
10 > *JMP ->4*
|dd00dd|11 > FE_FREE $4|
12 > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,51 @@
<slide>
<title>IF with ELSE</title>
<table class="two">
<tr>
<td>
<example inline="1">
if ( |0000dd|$a| == |00dd00|3.1415926| ) {
echo "Circles";
} else {
echo "Squares";
}
</example>
</td>
<td>
<example inline="1">AST_STMT_LIST
0: AST_IF
0: AST_IF_ELEM
cond: AST_BINARY_OP
flags: BINARY_IS_EQUAL (17)
left: AST_VAR
name: "a"
right: 3.1415926
stmts: AST_STMT_LIST
0: AST_ECHO
expr: "Circles"
1: AST_IF_ELEM
cond: null
stmts: AST_STMT_LIST
0: AST_ECHO
expr: "Squares"</example>
</td>
</tr></table>
<example inline="1">
compiled vars: |0000dd|!0 = $a|
line #* E I O op return operands
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 0 E > EXT_STMT
1 IS_EQUAL ~1 |0000dd|!0|, 3.14159
2 > *JMPZ* ~1, ->|00dddd|6|
3 3 > EXT_STMT
4 ECHO 'Circles'
5 > *JMP* ->|00dddd|8|
5 |00dddd|6| > EXT_STMT
7 ECHO 'Squares'
|00dddd|8| > > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,36 @@
<slide>
<title>IF</title>
<example inline="1">
if ( |0000dd|$a| == |00dd00|42| )
{
echo "To life, the universe, and everything.\n";
}
</example>
<example inline="1">
AST_STMT_LIST
0: AST_IF
0: AST_IF_ELEM
cond: AST_BINARY_OP
flags: BINARY_IS_EQUAL (17)
left: AST_VAR
|0000dd|name: "a"|
right: |00dd00|42|
stmts: AST_STMT_LIST
0: AST_ECHO
expr: "To life, the universe, and everything.
</example>
<example inline="1">
compiled vars: |0000dd|!0 = $a|
line #* E I O op return operands
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 0 E > EXT_STMT
1 IS_EQUAL |dd0000|~1| |0000dd|!0|, |00dd00|42|
2 > *JMPZ* |dd0000|~1|, ->|00dddd|5|
4 3 > EXT_STMT
4 ECHO 'To+life%2C+the+universe%2C+and+everything.%0A'
|00dddd|5| > > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,33 @@
<slide>
<title>TRY … CATCH … FINALLY</title>
<example inline="1">&amp;lt;?php
try {
echo "in try";
} *catch* ( Exception1 $e ) {
echo "exception 1 thrown";
} *catch* ( Exception2 $e ) {
echo "exception 2 thrown";
|00dd00|} finally {|
|0000dd|echo "in finally";|
}
echo "after";
</example>
<example inline="1">
line #* E I O op return operands
3 0 E > ECHO 'in+try'
1 > JMP |00dd00|->7|
4 2 *E > > CATCH* 'Exception1', !0, |dd00dd|->5|
5 3 > ECHO 'exception+1+thrown'
4 > JMP |00dd00|->7|
6 |dd00dd|5| *E > > CATCH* 'Exception2', !0
7 6 > ECHO 'exception+2+thrown'
8 |00dd00|7 > > FAST_CALL| ->9
8 > > JMP ->11
9 |0000dd|9 > ECHO 'in+finally'|
|0000dd|10 > FAST_RET|
11 11 > ECHO 'after'
12 > RETURN 1
</example>
</slide>

View File

@@ -0,0 +1,23 @@
<slide>
<title>WHILE</title>
<example inline="1">&amp;lt;?php
|dd0000|$i = 10;|
*while* ( |00dd00|--$i| ) {
|0000dd|echo $i;|
}
</example>
<example inline="1">compiled vars: !0 = $i
line #* E I O op fetch ext return operands
2 0 E > EXT_STMT
1 |dd0000|ASSIGN !0, 10|
3 2 EXT_STMT
3 > *JMP* ->|dd00dd|6|
4 4 > EXT_STMT
5 |0000dd|ECHO !0|
3 |dd00dd|6| > |00dd00|PRE_DEC $2 !0|
7 > |00dd00|JMPNZ $2, ->4|
8 > > RETURN 1
</example>
</slide>

BIN
slides/internals/jumps.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Jumps</title>
<image align="center" filename="jumps.jpg" attr="Thor-Wiggo Skille (http://www.nfk.no/Artikkel.aspx?AId=25071&amp;back=1&amp;MId1=4557&amp;MId2=&amp;MId3=&amp;)"/>
</slide>

BIN
slides/internals/loops.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Complex Loops</title>
<image align="center" filename="loops.png" attr="http://xkcd.com/657"/>
</slide>

View File

@@ -0,0 +1,17 @@
<slide>
<title>Tokenization</title>
<list>
<bullet>It's a big state machine starting with %INITIAL%</bullet>
<bullet>States: %INITIAL%, %ST_IN_SCRIPTING%, %ST_DOUBLE_QUOTES%, %ST_NOWDOC%…</bullet>
<bullet>Tokens can change the state:
<example><![CDATA[<INITIAL>"<?php"([ \t]|{NEWLINE}) {
HANDLE_NEWLINE(yytext[yyleng-1]);
BEGIN(ST_IN_SCRIPTING);
RETURN_TOKEN(T_OPEN_TAG);
} ]]></example>
</bullet>
<bullet>No *meaning* is given to these tokens</bullet>
<bullet>PHP comes with a *tokenizer* extension</bullet>
</list>
</slide>

View File

@@ -0,0 +1,49 @@
<slide>
<title>Tokenization</title>
<div effect="fade-out">
<blurb>Example script:</blurb>
<example inline="1"><![CDATA[&lt;?php
namespace DramIO;
class Whisky
{
private $name;
public function __construct( $name )
{
$this->name = $name;
}
public function drink()
{
echo "Drinking {$this->name}\n";
}
}
?>]]></example>
</div>
<div effect="fade-in">
<blurb>Example script:</blurb>
<example inline="1"><![CDATA[&lt;?php
namespace DramIO;
class Whisky
{
private $name;
public function __construct($name)
{
$this->name = $name;␃]]></example>
<blurb>In tokens:</blurb>
<example inline="1"><![CDATA[*T_OPEN_TAG* &lt;?php
*T_NAMESPACE* |777777|T_WS| *T_NS_SEPARATOR* *T_STRING* DramIO ; |777777|T_WS|
*T_CLASS* |777777|T_WS| *T_NS_SEPARATOR* *T_STRING* Whisky |777777|T_WS|
{ |777777|T_WS|
*T_PRIVATE* |777777|T_WS| *T_VARIABLE* $name ; |777777|T_WS|
*T_PUBLIC* |777777|T_WS| *T_FUNCTION* |777777|T_WS| *T_STRING* __construct ( *T_VARIABLE* $name ) |777777|T_WS|
{ |777777|T_WS|
*T_VARIABLE* $this *T_OBJECT_OPERATOR* -> *T_STRING* name |777777|T_WS| = |777777|T_WS| *T_VARIABLE* $name ;
]]></example>
</div>
</slide>

View File

@@ -0,0 +1,18 @@
<slide>
<title>Recap</title>
<list>
<bullet>Stages:<br/>Code → Tokens → Parsing → AST → Byte Code</bullet>
<bullet>All looping structures are jumps</bullet>
<bullet>Code analysis for Fun and Profit</bullet>
</list>
<break/>
<blurb>*Tools*</blurb>
<list>
<bullet>PHP's tokenizer: http://php.net/tokenizer</bullet>
<bullet>Nikita's AST extension: https://github.com/nikic/php-ast</bullet>
<bullet>VLD: https://pecl.php.net/vld</bullet>
</list>
</slide>

BIN
slides/internals/recap.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Recap</title>
<image align="center" filename="recap.jpg" attr="Jens Johnsson - https://www.pexels.com/photo/mountains-nature-arrow-guide-66100/ - CC0"/>
</slide>

BIN
slides/internals/ring.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 KiB

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Rings</title>
<image align="center" filename="ring.png" attr="© OpenStreetMap contributors"/>
</slide>

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

View File

@@ -0,0 +1,327 @@
<slide>
<title>Abstract Syntax Tree</title>
<blurb>Raw output from %ast\parse_code% function:</blurb>
<example>
object(ast\Node)#1 (4) {
["kind"]=>
int(133)
["flags"]=>
int(0)
["lineno"]=>
int(1)
["children"]=>
array(2) {
[0]=>
object(ast\Node)#2 (4) {
["kind"]=>
int(257)
["flags"]=>
int(0)
["lineno"]=>
int(2)
["children"]=>
array(1) {
["name"]=>
object(ast\Node)#3 (4) {
["kind"]=>
int(2048)
["flags"]=>
int(2)
["lineno"]=>
int(2)
["children"]=>
array(1) {
["name"]=>
string(6) "DramIO"
}
}
}
}
[1]=>
object(ast\Node\Decl)#4 (7) {
["kind"]=>
int(69)
["flags"]=>
int(0)
["lineno"]=>
int(4)
["children"]=>
array(3) {
["extends"]=>
NULL
["implements"]=>
NULL
["stmts"]=>
object(ast\Node)#5 (4) {
["kind"]=>
int(133)
["flags"]=>
int(0)
["lineno"]=>
int(5)
["children"]=>
array(3) {
[0]=>
object(ast\Node)#6 (4) {
["kind"]=>
int(139)
["flags"]=>
int(1024)
["lineno"]=>
int(6)
["children"]=>
array(1) {
[0]=>
object(ast\Node)#7 (4) {
["kind"]=>
int(774)
["flags"]=>
int(0)
["lineno"]=>
int(6)
["children"]=>
array(2) {
["name"]=>
string(4) "name"
["default"]=>
NULL
}
}
}
}
[1]=>
object(ast\Node\Decl)#8 (7) {
["kind"]=>
int(68)
["flags"]=>
int(256)
["lineno"]=>
int(8)
["children"]=>
array(4) {
["params"]=>
object(ast\Node)#9 (4) {
["kind"]=>
int(137)
["flags"]=>
int(0)
["lineno"]=>
int(8)
["children"]=>
array(1) {
[0]=>
object(ast\Node)#10 (4) {
["kind"]=>
int(773)
["flags"]=>
int(0)
["lineno"]=>
int(8)
["children"]=>
array(3) {
["type"]=>
NULL
["name"]=>
string(4) "name"
["default"]=>
NULL
}
}
}
}
["uses"]=>
NULL
["stmts"]=>
object(ast\Node)#11 (4) {
["kind"]=>
int(133)
["flags"]=>
int(0)
["lineno"]=>
int(9)
["children"]=>
array(1) {
[0]=>
object(ast\Node)#12 (4) {
["kind"]=>
int(517)
["flags"]=>
int(0)
["lineno"]=>
int(10)
["children"]=>
array(2) {
["var"]=>
object(ast\Node)#13 (4) {
["kind"]=>
int(513)
["flags"]=>
int(0)
["lineno"]=>
int(10)
["children"]=>
array(2) {
["expr"]=>
object(ast\Node)#14 (4) {
["kind"]=>
int(256)
["flags"]=>
int(0)
["lineno"]=>
int(10)
["children"]=>
array(1) {
["name"]=>
string(4) "this"
}
}
["prop"]=>
string(4) "name"
}
}
["expr"]=>
object(ast\Node)#15 (4) {
["kind"]=>
int(256)
["flags"]=>
int(0)
["lineno"]=>
int(10)
["children"]=>
array(1) {
["name"]=>
string(4) "name"
}
}
}
}
}
}
["returnType"]=>
NULL
}
["endLineno"]=>
int(11)
["name"]=>
string(11) "__construct"
["docComment"]=>
NULL
}
[2]=>
object(ast\Node\Decl)#16 (7) {
["kind"]=>
int(68)
["flags"]=>
int(256)
["lineno"]=>
int(13)
["children"]=>
array(4) {
["params"]=>
object(ast\Node)#17 (4) {
["kind"]=>
int(137)
["flags"]=>
int(0)
["lineno"]=>
int(13)
["children"]=>
array(0) {
}
}
["uses"]=>
NULL
["stmts"]=>
object(ast\Node)#18 (4) {
["kind"]=>
int(133)
["flags"]=>
int(0)
["lineno"]=>
int(14)
["children"]=>
array(1) {
[0]=>
object(ast\Node)#19 (4) {
["kind"]=>
int(282)
["flags"]=>
int(0)
["lineno"]=>
int(15)
["children"]=>
array(1) {
["expr"]=>
object(ast\Node)#20 (4) {
["kind"]=>
int(131)
["flags"]=>
int(0)
["lineno"]=>
int(15)
["children"]=>
array(3) {
[0]=>
string(9) "Drinking "
[1]=>
object(ast\Node)#21 (4) {
["kind"]=>
int(513)
["flags"]=>
int(0)
["lineno"]=>
int(15)
["children"]=>
array(2) {
["expr"]=>
object(ast\Node)#22 (4) {
["kind"]=>
int(256)
["flags"]=>
int(0)
["lineno"]=>
int(15)
["children"]=>
array(1) {
["name"]=>
string(4) "this"
}
}
["prop"]=>
string(4) "name"
}
}
[2]=>
string(1) "
"
}
}
}
}
}
}
["returnType"]=>
NULL
}
["endLineno"]=>
int(16)
["name"]=>
string(5) "drink"
["docComment"]=>
NULL
}
}
}
}
["endLineno"]=>
int(17)
["name"]=>
string(6) "Whisky"
["docComment"]=>
NULL
}
}
}
</example>
</slide>

View File

@@ -0,0 +1,88 @@
<slide>
<title>Abstract Syntax Tree (formatted)</title>
<div effect="fade-out">
<example inline="1">AST_STMT_LIST
0: AST_CONST
1: *AST_CLASS*
flags: 0
name: Whisky
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_DECL
flags: MODIFIER_PRIVATE (1024)
0: AST_PROP_ELEM
name: "name"
default: null
1: *AST_METHOD*
flags: *MODIFIER_PUBLIC* (256)
name: *__construct*
params: AST_PARAM_LIST
0: AST_PARAM
flags: 0
type: null
name: "name"
default: null
uses: null
*stmts: AST_STMT_LIST*
0: AST_ASSIGN
var: AST_PROP
expr: AST_VAR
name: "this"
prop: "name"
expr: AST_VAR
name: "name"
returnType: null
2: AST_METHOD
flags: MODIFIER_PUBLIC (256)
name: drink
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
0: AST_ECHO
expr: AST_ENCAPS_LIST
0: "Drinking "
1: AST_PROP
expr: AST_VAR
name: "this"
prop: "name"
2: "
"
returnType: null</example>
</div>
<div effect="fade-in">
<example inline="1">
|0000dd|public| function |00dd00|__construct|( |0000dd|$name| )
{
|00dddd|$this->name| |dd00dd|=| |ff0000|$name|
}
</example>
<br/>
<example inline="1">
1: AST_METHOD
flags: MODIFIER_PUBLIC (256)
name: |00dd00|__construct|
params: AST_PARAM_LIST
0: AST_PARAM
flags: 0
type: null
name: |0000dd|"name"|
default: null
uses: null
stmts: AST_STMT_LIST
0: |dd00dd|AST_ASSIGN|
var: |00dddd|AST_PROP|
expr: AST_VAR
name: |00dddd|"this"|
prop: |00dddd|"name"|
expr: AST_VAR
name: |ff0000|"name"|
returnType: null
</example>
</div>
</slide>

View File

@@ -0,0 +1,30 @@
<slide>
<title>Scanner Rules</title>
<list>
<bullet>Gives Meaning to Tokens</bullet>
<bullet>Constructs AST through Rules:
<example inline="1">class_declaration_statement:
class_modifiers T_CLASS |dd00dd|{ $&amp;lt;num>$ = CG(zend_lineno); }|
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ $$ = *zend_ast_create_decl*(ZEND_AST_CLASS, $1, $&amp;lt;num>3, $7, *zend_ast_get_str*($4), $5, $6, $9, NULL); }
|
;
</example>
<example inline="1">
case 167:
#line 493 "/home/derick/dev/php/php-src.git/Zend/zend_language_parser.y"
|dd00dd|{ (yyval.num) = CG(zend_lineno); }|
break;
case 168:
#line 495 "/home/derick/dev/php/php-src.git/Zend/zend_language_parser.y"
{ (yyval.ast) = *zend_ast_create_decl*(ZEND_AST_CLASS, (yyvsp[(1) - (10)].num), (yyvsp[(3) - (10)].num), (yyvsp[(7) - (10)].str), *zend_ast_get_str*((yyvsp[(4) - (10)].ast)), (yyvsp[(5) - (10)].ast), (yyvsp[(6) - (10)].ast), (yyvsp[(9) - (10)].ast), NULL); }
break;
</example>
</bullet>
</list>
</slide>

View File

@@ -0,0 +1,31 @@
<slide>
<title>Scanner Rules</title>
<example inline="1">top_statement:
statement { $$ = $1; }
| function_declaration_statement { $$ = $1; }
| |0000dd|class_declaration_statement| { $$ = $1; }
| trait_declaration_statement { $$ = $1; }
;
|0000dd|class_declaration_statement|:
|dd00dd|class_modifiers| T_CLASS { $&amp;lt;num>$ = CG(zend_lineno); }
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ $$ = *zend_ast_create_decl*(ZEND_AST_CLASS, $1, $&amp;lt;num>3, $7, *zend_ast_get_str*($4), $5, $6, $9, NULL); }
| T_CLASS { $&amp;lt;num>$ = CG(zend_lineno); }
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ $$ = *zend_ast_create_decl*(ZEND_AST_CLASS, 0, $&amp;lt;num>2, $6, *zend_ast_get_str*($3), $4, $5, $8, NULL); }
;
|dd00dd|class_modifiers|:
|00dddd|class_modifier| { $$ = $1; }
| |dd00dd|class_modifiers| |00dddd|class_modifier| { $$ = *zend_add_class_modifier*($1, $2); }
;
|00dddd|class_modifier|:
T_ABSTRACT { $$ = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
| T_FINAL { $$ = ZEND_ACC_FINAL; }
;
</example>
</slide>

BIN
slides/internals/stages.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

View File

@@ -0,0 +1,54 @@
<slide>
<title style="center">Stages</title>
<break lines="2"/>
<div effect="fade-out">
<div class="center">
<blurb>Parse Script</blurb>
<blurb>Create Logical Representation</blurb>
<blurb>Create Executable Code</blurb>
<blurb>Execute Bytecode</blurb>
</div>
</div>
<div effect="fade-in-out">
<div class="center">
<blurb>*Parse Script*</blurb>
<blurb class="small">Convert code into Tokens</blurb><br/>
<blurb>Create Logical Representation</blurb>
<blurb>Create Executable Code</blurb>
<blurb>Execute Bytecode</blurb>
</div>
</div>
<div effect="fade-in-out">
<div class="center">
<blurb>Parse Script</blurb><br/>
<blurb>*Create Logical Representation*</blurb>
<blurb class="small">Convert Tokens into Abstract Syntax Tree (AST)</blurb><br/>
<blurb>Create Executable Code</blurb>
<blurb>Execute Bytecode</blurb>
</div>
</div>
<div effect="fade-in-out">
<div class="center">
<blurb>Parse Script</blurb>
<blurb>Create Logical Representation</blurb><br/>
<blurb>*Create Executable Code*</blurb>
<blurb class="small">Convert AST into Opcodes (Bytecode)</blurb><br/>
<blurb>Execute Bytecode</blurb>
</div>
</div>
<div effect="fade-in">
<div class="center">
<blurb>Parse Script</blurb>
<blurb>Create Logical Representation</blurb>
<blurb>Create Executable Code</blurb><br/>
<blurb>*Execute Bytecode*</blurb>
<blurb class="small">Run the Opcodes with the Zend Engine</blurb><br/>
</div>
</div>
</slide>

View File

@@ -0,0 +1,9 @@
<slide>
<title>Agenda</title>
<list>
<bullet>Stages</bullet>
<bullet>Conversion Stages</bullet>
<bullet>Conclusion</bullet>
</list>
</slide>

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Parsing</title>
<image align="center" filename="tokens.jpg" attr="$1LENCE D00600D at English Wikipedia"/>
</slide>

View File

@@ -0,0 +1,4 @@
<slide style="title">
<title>Stages</title>
<image align="center" filename="stages.jpg" attr=""/>
</slide>

BIN
slides/internals/tokens.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

View File

@@ -6,7 +6,7 @@
<blurb>Derick Rethans</blurb>
<list>
<bullet>I'm *Dutch/British* living in London</bullet>
<bullet>I'm ---Dutch/British--- European, living in London</bullet>
<bullet>One of the PHP/HHVM *MongoDB* driver maintainers</bullet>
<bullet>Author of the PHP debugger tool *Xdebug*, PHP's Date/Time/Timezone support, and a bunch of other PHP extensions</bullet>
<bullet>I ♥🌍 maps, I ♥🍺 beer, I ♥🥃 whisky</bullet>

View File

@@ -1,7 +1,7 @@
{use $node, $pres}
{var $class = get_attribute( $node, 'class' )}
{var $effect = get_attribute( $node, 'effect' )}
<div{if $effect} class='effect-{$effect}'{/if}{if $class} class="{$class}"{/if}>
<div{if $effect || $class} class='{/if}{if $effect}effect-{$effect}{/if} {if $class}{literal} {/literal}{$class}{/if} {if $effect || $class}'{/if}>
{foreach $node->childNodes as $child}
{if is_set( $child->tagName )}
{include $child->tagName . '.ezt' send $child as $node, $pres}