2012-07-23 13 views
8

Estoy tratando de entender el código de operación para un código simple.Comprender el código de operación PHP en una declaración if

El código es:

<?php 

$a = TRUE; 

$b = FALSE; 

if($a && $b) { 
    echo 'done'; 
} 

El código de operación para el código anterior es:

php -dvld.active=1 test.php 
Finding entry points 
Branch analysis from position: 0 
Jump found. Position 1 = 3, Position 2 = 4 
Branch analysis from position: 3 
Jump found. Position 1 = 5, Position 2 = 7 
Branch analysis from position: 5 
Jump found. Position 1 = 7 
Branch analysis from position: 7 
Return found 
Branch analysis from position: 7 
Branch analysis from position: 4 
filename:  /home/starlays/learning/test.php 
function name: (null) 
number of ops: 8 
compiled vars: !0 = $a, !1 = $b 
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    3  0 > ASSIGN             !0, true 
    5  1  ASSIGN             !1, false 
    7  2 > JMPZ_EX           ~2  !0, ->4 
     3 > BOOL            ~2  !1 
     4 > > JMPZ              ~2, ->7 
    8  5 > ECHO              'done' 
    9  6 > JMP              ->7 
    10  7 > > RETURN             1 

branch: # 0; line:  3- 7; sop:  0; eop:  2; out1: 3; out2: 4 
branch: # 3; line:  7- 7; sop:  3; eop:  3; out1: 4 
branch: # 4; line:  7- 7; sop:  4; eop:  4; out1: 5; out2: 7 
branch: # 5; line:  8- 9; sop:  5; eop:  6; out1: 7 
branch: # 7; line: 10- 10; sop:  7; eop:  7 
path #1: 0, 3, 4, 5, 7, 
path #2: 0, 3, 4, 7, 
path #3: 0, 4, 5, 7, 
path #4: 0, 4, 7, 

Estoy tratando de entender lo que está sucediendo en la línea 7, cómo se realiza la evaluación? ¿Cuántos valores ingresa en la expresión de if para evaluación? Ingresa 3 valores, o ingresa los 2 valores el valor de $ a y el valor de $ b y la expresión de los paréntesis de if se evalúa después?

He leído el manual de JMPZ_EX, he entendido lo que está sucediendo en el código de operación hasta el paso 2, después de eso está un poco mezclado y es muy difícil para mí entender cuáles son los pasos exactos que php es obra.

Otra cosa que necesito entender es cuáles son todas las ramas en el código de operación, ¿cuál de todas las ramas se usará al final?

+0

'&&' es un operador de cortocircuito. –

+0

@KarolyHorvath que yo sé, necesito entender los pasos que está haciendo php desde el código de operación anterior. – Starlays

+0

Solo digo que ya sabes cómo debe comportarse, así que ... –

Respuesta

2

menos que sea experto en ASM, creo que la forma más fácil de entender lo que está sucediendo está mirando el mismo código mediante la lectura de su (casi) 1: 1 Representación en PHP:

if(!$a) goto end; 
if(!$b) goto end; 
echo 'done'; 
end: return 0; 

La representación intermedia se basa en las negaciones de sus cláusulas reales para dar un salto sobre el código contenido en el bloque if.

Si realmente quiere entender cómo PHP transforma su entrada a este conjunto de códigos de operación, tendrá que aprender acerca de las partes internas de PHP, pero no antes de estudiar the dragon book, en particular las partes sobre representación intermedia, que es parte de la compilación .

El resto de los códigos de operación son "ruido de fondo", valores intermedios o incluso una instrucción que no tiene sentido 9 6 > JMP ->7 que simplemente existe probablemente porque no tenía sentido hacer el esfuerzo de hacer que el analizador PHP escupiera el conjunto de códigos de operación más óptimo para el ZendVM que ejecutará.

2
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    3  0 > ASSIGN             !0, true 
    5  1  ASSIGN             !1, false 
    7  2 > JMPZ_EX           ~2  !0, ->4 
     3 > BOOL            ~2  !1 
     4 > > JMPZ              ~2, ->7 
    8  5 > ECHO              'done' 
    9  6 > JMP              ->7 
    10  7 > > RETURN             1 

A juzgar por los números de línea #

0 assigns true to !0, !0 is just the internal representation of $A 
1 assigns true to !1, !1 is $B 

JMPZ significa que saltar al código si el valor es 0. No estoy seguro de la diferencia específica de JMPZ_EX parece que permite la retorno de un resultado booleano.

Así:

2 JMPZ_EX, Jump to #4 (->4) if !0 ($A) is 0 (FALSE) and assign the result to ~2 

3 BOOL !1 return ~2. ~2 is now equal to the BOOLean value of !1 ($B) 
4 JMPZ ~2, Jump to #7 if ~2 is zero 

5 ECHO, our echo statement. If any of the JMPZ had jumped, this part would be skipped. 
6 JMP -7, jumps to #7 
7 RETURN, ends the function call 

Algunas notas:

  • parece que el JMPZ_EX es innecesario en este caso, pero sería útil en más compleja si las declaraciones en las que necesita utilizar el valor calculando otros valores
  • 6 JMP -7 probablemente esté ahí para permitir un bloque else. Si esta era la parte principal del bloque if, terminarla podría saltar sobre la parte del código que era el bloque else.