> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On 
> Behalf Of Sam Tregar
> Sent: Monday, July 11, 2005 8:00 PM
> To: Emanuele Zeppieri
> Cc: html-template-users@lists.sourceforge.net
> Subject: Re: [htmltmpl] (no subject)
> 
> 
> On Mon, 11 Jul 2005, Emanuele Zeppieri wrote:
> 
> > Well, I'm probably missing something (or everything), but 
> it seems to me
> > that the following compiled code layout could solve the problem:
> > 
> >     JUMP to A IF false
> >     ... # first true instruction
> >     ...
> >     ... # last true instruction
> >     JUMP TO B
> > A:  ... # first false instruction
> >     ...
> >     ... # last false instruction
> > B:  ... # normal execution after the IF/ELSE, if any...
> 
> Yup, that would do it.  That's much easier than trying to store state
> from the first one.  So, when can I see a patch?


Here it is Sam.

It guarantees that any conditional predicate is never re-evaluated and,
as an extra bonus, it also speeds up the output() execution in presence
of a TMPL_ELSE tag.

It passed all the tests under both Linux and Windows and I've also added
a new test for HTML::Template::Expr (05random.t) which reproduces the
case showed by Jochen Cichon.

The patch is against Template.pm ver. 2.7.
The patch is attached to this message (as well as the new test) and also
listed below.

Feel free to remove my name from the comments (left there merely to
easily find the relevant lines, just in case a correction is needed or a
further refinement comes to my mind).

Cheers,
Emanuele.


--- Template.pm.original        Sat Jun 26 08:57:09 2004
+++ Template.pm Wed Jul 13 03:35:03 2005
@@ -897,7 +897,7 @@
 # accesses into "objects".  I used to use 'use constant' but that
 # seems to cause occasional irritating warnings in older Perls.
 package HTML::Template::LOOP;
-sub TEMPLATE_HASH () { 0; }
+sub TEMPLATE_HASH () { 0 };
 sub PARAM_SET     () { 1 };
 
 package HTML::Template::COND;
@@ -908,6 +908,7 @@
 sub JUMP_IF_TRUE       () { 2 };
 sub JUMP_ADDRESS       () { 3 };
 sub WHICH              () { 4 };
+sub UNCONDITIONAL_JUMP () { 5 };
 sub WHICH_IF           () { 0 };
 sub WHICH_UNLESS       () { 1 };
 
@@ -2183,7 +2184,15 @@
        
        my $else =
HTML::Template::COND->new($cond->[HTML::Template::COND::VARIABLE]);
        $else->[HTML::Template::COND::WHICH] =
$cond->[HTML::Template::COND::WHICH];
-       $else->[HTML::Template::COND::JUMP_IF_TRUE] = not
$cond->[HTML::Template::COND::JUMP_IF_TRUE];
+
+       # <Emanuele Zeppieri>
+       # Removed because now unnecessary, as we'll unconditionally jump
over
+       #$else->[HTML::Template::COND::JUMP_IF_TRUE] = not
$cond->[HTML::Template::COND::JUMP_IF_TRUE];
+
+       # This is to mark this COND opcode as generated by a TMPL_ELSE
tag,
+       # so that we can just jump over during the output() execution.
+       $else->[HTML::Template::COND::UNCONDITIONAL_JUMP] = 1;
+       # </Emanuele Zeppieri>
        
        # need end-block resolution?
        if (defined($cond->[HTML::Template::COND::VARIABLE_TYPE])) {
@@ -2201,7 +2210,7 @@
        # the IF fails and falls though, output will reach the else
        # and jump to the /if address.
        $cond->[HTML::Template::COND::JUMP_ADDRESS] = $#pstack;
-       
+               
       } elsif ($which eq 'TMPL_INCLUDE') {
        # handle TMPL_INCLUDEs
        $options->{debug} and print STDERR "### HTML::Template Debug ###
$fname : line $fcounter : INCLUDE $name \n";
@@ -2657,7 +2666,12 @@
         croak("HTML::Template->output() : fatal error in loop output :
$@") 
           if $@;
       }
-    } elsif ($type eq 'HTML::Template::COND') {
+       } elsif ($type eq 'HTML::Template::COND') {
+       
+               if ($line->[HTML::Template::COND::UNCONDITIONAL_JUMP]) {
+                       $x = $line->[HTML::Template::COND::JUMP_ADDRESS]
+               } else {
+       
       if ($line->[HTML::Template::COND::JUMP_IF_TRUE]) {
         if ($line->[HTML::Template::COND::VARIABLE_TYPE] ==
HTML::Template::COND::VARIABLE_TYPE_VAR) {
           if (defined ${$line->[HTML::Template::COND::VARIABLE]}) {
@@ -2689,6 +2703,9 @@
              not scalar
@{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SE
T]});
         }
       }
+      
+               }
+       
     } elsif ($type eq 'HTML::Template::NOOP') {
       next;
     } elsif ($type eq 'HTML::Template::DEFAULT') {

Attachment: Template.pm.patch
Description: Binary data

Attachment: 05random.t
Description: Binary data

Reply via email to