How does Perl’s interpreter do if-statements? I wanted to try to implement a simple Lazy-Basic-Block-Versioning for if-statements that use ref as a predicate, and maybe subsequently for sub-routines as well.
After studying the source code I see OP codes for everything but control flow. My interpreter experience is quite limited, but I would assume to see a OP_IF that would pop the stack for it’s predicates OP codes or something along those lines. I found KEY_if which comes from the Yacc grammar, which then subsequently is used in toke.c and translated to a KW_IF, but I can’t find where KW_IF is actually used.
I originally intended to just add some basic optimization with global state to peep.c, but since there is no OP_IF I’m struggling to see the big-picture of how control flow is handled.
>Solution :
if gets compiled into an and or or op.
perl -MO=Concise,-exec -e'if ( f() ) { ... }'
1 <0> enter v
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s
4 <#> gv[*f] s/EARLYCV
5 <1> entersub[t2] sKS/TARG
6 <|> and(other->7) vK/1
7 <0> pushmark s
8 <$> const[PV "Unimplemented"] s
9 <@> die vK/1
a <@> leave[1 ref] vKP/REFC
-e syntax OK
perl -MO=Concise,-exec -e'if ( !f() ) { ... }'
1 <0> enter v
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s
4 <#> gv[*f] s/EARLYCV
5 <1> entersub[t2] sKS/TARG
6 <|> or(other->7) vK/1
7 <0> pushmark s
8 <$> const[PV "Unimplemented"] s
9 <@> die vK/1
a <@> leave[1 ref] vKP/REFC
-e syntax OK
The opcode name from Concise maps to a function named pp_name in pp*.c (with a few exceptions).