Changeset 194

Show
Ignore:
Timestamp:
04/06/06 16:57:25 (3 years ago)
Author:
hans
Message:

Rewrote fix for sf.net bug #1442923. This should get rid of all 'Invalid opcode: 99/4/1' errors.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/ChangeLog

    r193 r194  
     12006-04-06  Hans Rakers <hans at parse dot nl> 
     2 
     3        * Reverted the change to the handling of ZEND_BRK made by me on 
     4          2006-03-17 since it wasn't working as it should. Since this 
     5          reintroduces sf.net bug #1442923 i added some code to prevent this 
     6          bug using a different approach, by restoring operand types changed 
     7          by build_cfg if build_cfg exits with exit code 0. 
     8 
     9          Since php-5.1 some opcode handlers expect a strict set of operand 
     10          types, anything else results in 'Invalid opcode' errors. Since 
     11          build_cfg changes some operand types these changes need to be 
     12          reverted once the optimizer finishes. For now the only opcode to 
     13          which this all applies is ZEND_FETCH_CONSTANT, which expects 
     14          either a CONST or a UNUSED in op1 and a CONST in op2 (See 
     15          zend_vm_def.h) 
     16 
    1172006-04-04  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
    218 
  • eaccelerator/trunk/optimize.c

    r191 r194  
    28212821                                                        op_array->opcodes[jmp_to->brk].opcode == ZEND_FREE)) 
    28222822                                                { 
    2823                                                         break
     2823                                                        goto brk_failed
    28242824                                                } 
    28252825                                                offset = jmp_to->parent; 
     
    32273227          if (op->opcode == ZEND_DO_FCALL_BY_NAME) { 
    32283228            op->op1.op_type = IS_UNUSED; 
    3229           } else if (op->opcode == ZEND_FETCH_CONSTANT) { 
     3229          } else if (op->opcode == ZEND_FETCH_CONSTANT && op->op1.op_type == IS_VAR) { 
    32303230            op->op1.u.var = VAR_VAL(assigned[r]); 
     3231            /* restore op1 type from VAR to CONST (the opcode handler expects this or bombs out with invalid opcode) */ 
    32313232            op->op1.op_type = IS_CONST; 
    32323233          } else { 
     
    32873288} 
    32883289 
     3290void restore_operand_types(zend_op_array *op_array) { 
     3291        zend_op* op = op_array->opcodes; 
     3292        int len = op_array->last; 
     3293        int line_num; 
     3294 
     3295        for (line_num=0; line_num < len; op++,line_num++) 
     3296        { 
     3297          if (op->opcode == ZEND_FETCH_CONSTANT && op->op1.op_type == IS_VAR) { 
     3298            /* restore op1 type from VAR to CONST (the opcode handler expects this or bombs out with invalid opcode) */ 
     3299            op->op1.op_type = IS_CONST; 
     3300          } 
     3301        } 
     3302} 
     3303 
    32893304/* 
    32903305 * Main Optimization Routine 
     
    33583373    free_alloca(global); 
    33593374  } 
     3375#  ifdef ZEND_ENGINE_2_1 
     3376  else { 
     3377    /* build_cfg encountered some nested ZEND_BRK or ZEND_CONT's 
     3378       which it could not replace with JMP's 
     3379 
     3380       now restore the operand type changes that build_cfg had 
     3381       already applied, to prevent 'invalid opcode' errors 
     3382       on opcode handlers that expect a strict set of operand 
     3383       types since php-5.1 (like ZEND_FETCH_CONSTANT) 
     3384    */ 
     3385    restore_operand_types(op_array); 
     3386#  endif 
     3387  } 
    33603388  free_alloca(bb); 
    33613389}