From d5c5882d90fe6add24add3c67db7336090a24fb3 Mon Sep 17 00:00:00 2001
From: zesstra <zesstra@zesstra.de>
Date: Mon, 4 May 2009 17:40:36 +0200
Subject: [PATCH 2/2] Fixes insert_pop_value().

insert_pop_value() removes the last value from the stack. If possible, it
patches the code to prevent that value from being computed at all (by
removing the last expression). Unfortunately the function assumed that all
opertions have no data following in the bytecode. This patches changes it
and enabled optimization/removal of operations with data.

Signed-off-by: zesstra <zesstra@zesstra.de>
---
 src/prolang.y |  111 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 70 insertions(+), 41 deletions(-)

diff --git a/src/prolang.y b/src/prolang.y
index 7ea8e29..c01eac8 100644
--- a/src/prolang.y
+++ b/src/prolang.y
@@ -14145,58 +14145,87 @@ insert_pop_value (void)
  */
 
 {
-    if (last_expression == CURRENT_PROGRAM_SIZE-1)
+    /* We don't have to fear sideeffects and try to prevent
+     * the value from being generated if the last expression is not too long
+     * ago.
+     */
+    if (last_expression == CURRENT_PROGRAM_SIZE - 1)
     {
-        /* We don't have to fear sideeffects and try to prevent
-         * the value from being generated.
-         */
+         /* The following ops have no data in the bytecode. */
         switch ( mem_block[A_PROGRAM].block[last_expression])
         {
-        case F_ASSIGN:
-            mem_block[A_PROGRAM].block[last_expression] =
+                /* The following ops have no data in the bytecode. */
+            case F_ASSIGN:
+                mem_block[A_PROGRAM].block[last_expression] =
                 F_VOID_ASSIGN;
-            break;
-        case F_ADD_EQ:
-            mem_block[A_PROGRAM].block[last_expression] =
+                break;
+            case F_ADD_EQ:
+                mem_block[A_PROGRAM].block[last_expression] =
                 F_VOID_ADD_EQ;
-            break;
-        case F_PRE_INC:
-        case F_POST_INC:
-            mem_block[A_PROGRAM].block[last_expression] =
+                break;
+            case F_PRE_INC:
+            case F_POST_INC:
+                mem_block[A_PROGRAM].block[last_expression] =
                 F_INC;
-            break;
-        case F_PRE_DEC:
-        case F_POST_DEC:
-            mem_block[A_PROGRAM].block[last_expression] =
+                break;
+            case F_PRE_DEC:
+            case F_POST_DEC:
+                mem_block[A_PROGRAM].block[last_expression] =
                 F_DEC;
-            break;
-        case F_CONST0:
-        case F_CONST1:
-        case F_NCONST1:
-            mem_block[A_PROGRAM].current_size = last_expression;
-            break;
-        case F_CLIT:
-        case F_NCLIT:
-        case F_CSTRING0:
-        case F_CSTRING1:
-        case F_CSTRING2:
-            mem_block[A_PROGRAM].current_size = last_expression-1;
-            break;
-        case F_STRING:
-            mem_block[A_PROGRAM].current_size = last_expression-2;
-            break;
-        case F_NUMBER:
-            mem_block[A_PROGRAM].current_size = last_expression-4;
-            break;
-        default: ins_f_code(F_POP_VALUE);
+                break;
+            case F_CONST0:
+            case F_CONST1:
+            case F_NCONST1:
+                mem_block[A_PROGRAM].current_size = last_expression;
+                break;
+            default:
+                ins_f_code(F_POP_VALUE);
+                break;
         }
-        last_expression = -1;
+    }
+    else if (last_expression == CURRENT_PROGRAM_SIZE - 2)
+    {
+        /* The following ops are followed by 1 chars of data in the bytecode. */
+        switch ( mem_block[A_PROGRAM].block[last_expression])
+        {
+            case F_CLIT:
+            case F_NCLIT:
+            case F_CSTRING0:
+            case F_CSTRING1:
+            case F_CSTRING2:
+            case F_CSTRING3:
+                mem_block[A_PROGRAM].current_size = last_expression;
+                break;
+            default:
+                ins_f_code(F_POP_VALUE);
+                break;
+        }
+    }
+    else if (last_expression == CURRENT_PROGRAM_SIZE - 3)
+    {
+        /* The following ops are followed by 2 chars of data in the bytecode. */
+        if ( mem_block[A_PROGRAM].block[last_expression] == F_STRING)
+            mem_block[A_PROGRAM].current_size = last_expression;
+        else
+            ins_f_code(F_POP_VALUE);            
+    }
+    else if (last_expression == CURRENT_PROGRAM_SIZE - sizeof(p_int))
+    {
+        /* The following ops are followed by sizeof(p_int) chars of data in 
+         * the bytecode. */
+        if ( mem_block[A_PROGRAM].block[last_expression] == F_NUMBER)
+            mem_block[A_PROGRAM].current_size = last_expression;
+        else
+            ins_f_code(F_POP_VALUE);            
     }
     else
-        /* The last expression is too long ago: just pop whatever there
-         * is on the stack.
-         */
+    {
+        /* last expression unknown or too long ago - just pop whatever there
+         * is on the stack */
         ins_f_code(F_POP_VALUE);
+    }
+    
+    last_expression = -1;
 } /* insert_pop_value() */
 
 /*-------------------------------------------------------------------------*/
-- 
1.6.1

