int fullSpeedBench(char** fileNamesTable, int nbFiles)
{
  int fileIdx=0;
  char* orig_buff;
# define NB_COMPRESSION_ALGORITHMS 13
# define MINCOMPRESSIONCHAR '0'
  double totalCTime[NB_COMPRESSION_ALGORITHMS+1] = {0};
  double totalCSize[NB_COMPRESSION_ALGORITHMS+1] = {0};
# define NB_DECOMPRESSION_ALGORITHMS 7
# define MINDECOMPRESSIONCHAR '0'
# define MAXDECOMPRESSIONCHAR (MINDECOMPRESSIONCHAR + NB_DECOMPRESSION_ALGORITHMS)
  static char* decompressionNames[] = { "LZ4_decompress_fast", "LZ4_decompress_fast_withPrefix64k", "LZ4_decompress_fast_usingDict",
                                        "LZ4_decompress_safe", "LZ4_decompress_safe_withPrefix64k", "LZ4_decompress_safe_usingDict", "LZ4_decompress_safe_partial" };
  double totalDTime[NB_DECOMPRESSION_ALGORITHMS+1] = {0};

  // Loop for each file
  while (fileIdx<nbFiles)
  {
      FILE* inFile;
      char* inFileName;
      U64   inFileSize;
      size_t benchedSize;
      int nbChunks;
      int maxCompressedChunkSize;
      struct chunkParameters* chunkP;
      size_t readSize;
      char* compressed_buff; int compressedBuffSize;
      U32 crcOriginal;

      // Init
      stateLZ4   = malloc(LZ4_sizeofState());
      stateLZ4HC = malloc(LZ4_sizeofStateHC());

      // Check file existence
      inFileName = fileNamesTable[fileIdx++];
      inFile = fopen( inFileName, "rb" );
      if (inFile==NULL)
      {
        DISPLAY( "Pb opening %s\n", inFileName);
        return 11;
      }

      // Memory allocation & restrictions
      inFileSize = BMK_GetFileSize(inFileName);
      benchedSize = (size_t) BMK_findMaxMem(inFileSize) / 2;
      if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
      if (benchedSize < inFileSize)
      {
          DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", inFileName, (int)(benchedSize>>20));
      }

      // Alloc
      chunkP = (struct chunkParameters*) malloc(((benchedSize / (size_t)chunkSize)+1) * sizeof(struct chunkParameters));
      orig_buff = (char*) malloc((size_t)benchedSize);
      nbChunks = (int) ((int)benchedSize / chunkSize) + 1;
      maxCompressedChunkSize = LZ4_compressBound(chunkSize);
      compressedBuffSize = nbChunks * maxCompressedChunkSize;
      compressed_buff = (char*)malloc((size_t)compressedBuffSize);

      if(!orig_buff || !compressed_buff)
      {
        DISPLAY("\nError: not enough memory!\n");
        free(orig_buff);
        free(compressed_buff);
        free(chunkP);
        fclose(inFile);
        return 12;
      }

      // Init chunks data
      {
          int i;
          size_t remaining = benchedSize;
          char* in = orig_buff;
          char* out = compressed_buff;
          for (i=0; i<nbChunks; i++)
          {
              chunkP[i].id = i;
              chunkP[i].origBuffer = in; in += chunkSize;
              if ((int)remaining > chunkSize) { chunkP[i].origSize = chunkSize; remaining -= chunkSize; } else { chunkP[i].origSize = (int)remaining; remaining = 0; }
              chunkP[i].compressedBuffer = out; out += maxCompressedChunkSize;
              chunkP[i].compressedSize = 0;
          }
      }

      // Fill input buffer
      DISPLAY("Loading %s...       \r", inFileName);
      readSize = fread(orig_buff, 1, benchedSize, inFile);
      fclose(inFile);

      if(readSize != benchedSize)
      {
        DISPLAY("\nError: problem reading file '%s' !!    \n", inFileName);
        free(orig_buff);
        free(compressed_buff);
        free(chunkP);
        return 13;
      }

      // Calculating input Checksum
      crcOriginal = XXH32(orig_buff, (unsigned int)benchedSize,0);

      // Bench
      {
        int loopNb, nb_loops, chunkNb, cAlgNb, dAlgNb;
        size_t cSize=0;
        double ratio=0.;

        DISPLAY("\r%79s\r", "");
        DISPLAY(" %s : \n", inFileName);

        // Compression Algorithms
        for (cAlgNb=1; (cAlgNb <= NB_COMPRESSION_ALGORITHMS) && (compressionTest); cAlgNb++)
        {
            char* compressorName;
            int (*compressionFunction)(const char*, char*, int);
            void* (*initFunction)(const char*) = NULL;
            double bestTime = 100000000.;

            if ((compressionAlgo != ALL_COMPRESSORS) && (compressionAlgo != cAlgNb)) continue;

            switch(cAlgNb)
            {
            case 1 : compressionFunction = LZ4_compress; compressorName = "LZ4_compress"; break;
            case 2 : compressionFunction = local_LZ4_compress_limitedOutput; compressorName = "LZ4_compress_limitedOutput"; break;
            case 3 : compressionFunction = local_LZ4_compress_withState; compressorName = "LZ4_compress_withState"; break;
            case 4 : compressionFunction = local_LZ4_compress_limitedOutput_withState; compressorName = "LZ4_compress_limitedOutput_withState"; break;
            case 5 : compressionFunction = local_LZ4_compress_continue; initFunction = LZ4_create; compressorName = "LZ4_compress_continue"; break;
            case 6 : compressionFunction = local_LZ4_compress_limitedOutput_continue; initFunction = LZ4_create; compressorName = "LZ4_compress_limitedOutput_continue"; break;
            case 7 : compressionFunction = LZ4_compressHC; compressorName = "LZ4_compressHC"; break;
            case 8 : compressionFunction = local_LZ4_compressHC_limitedOutput; compressorName = "LZ4_compressHC_limitedOutput"; break;
            case 9 : compressionFunction = local_LZ4_compressHC_withStateHC; compressorName = "LZ4_compressHC_withStateHC"; break;
            case 10: compressionFunction = local_LZ4_compressHC_limitedOutput_withStateHC; compressorName = "LZ4_compressHC_limitedOutput_withStateHC"; break;
            case 11: compressionFunction = local_LZ4_compressHC_continue; initFunction = LZ4_createHC; compressorName = "LZ4_compressHC_continue"; break;
            case 12: compressionFunction = local_LZ4_compressHC_limitedOutput_continue; initFunction = LZ4_createHC; compressorName = "LZ4_compressHC_limitedOutput_continue"; break;
            case 13: compressionFunction = local_LZ4_compress_forceDict; initFunction = local_LZ4_resetDictT; compressorName = "LZ4_compress_forceDict"; break;
            default : DISPLAY("ERROR ! Bad algorithm Id !! \n"); free(chunkP); return 1;
            }

            for (loopNb = 1; loopNb <= nbIterations; loopNb++)
            {
                double averageTime;
                int milliTime;

                PROGRESS("%1i-%-26.26s : %9i ->\r", loopNb, compressorName, (int)benchedSize);
                { size_t i; for (i=0; i<benchedSize; i++) compressed_buff[i]=(char)i; }     // warmimg up memory

                nb_loops = 0;
                milliTime = BMK_GetMilliStart();
                while(BMK_GetMilliStart() == milliTime);
                milliTime = BMK_GetMilliStart();
                while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
                {
                    if (initFunction!=NULL) ctx = initFunction(chunkP[0].origBuffer);
                    for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
                    {
                        chunkP[chunkNb].compressedSize = compressionFunction(chunkP[chunkNb].origBuffer, chunkP[chunkNb].compressedBuffer, chunkP[chunkNb].origSize);
                        if (chunkP[chunkNb].compressedSize==0) DISPLAY("ERROR ! %s() = 0 !! \n", compressorName), exit(1);
                    }
                    if (initFunction!=NULL) free(ctx);
                    nb_loops++;
                }
                milliTime = BMK_GetMilliSpan(milliTime);

                averageTime = (double)milliTime / nb_loops;
                if (averageTime < bestTime) bestTime = averageTime;
                cSize=0; for (chunkNb=0; chunkNb<nbChunks; chunkNb++) cSize += chunkP[chunkNb].compressedSize;
                ratio = (double)cSize/(double)benchedSize*100.;
                PROGRESS("%1i-%-26.26s : %9i -> %9i (%5.2f%%),%7.1f MB/s\r", loopNb, compressorName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / bestTime / 1000.);
            }

            if (ratio<100.)
                DISPLAY("%-28.28s : %9i -> %9i (%5.2f%%),%7.1f MB/s\n", compressorName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / bestTime / 1000.);
            else
                DISPLAY("%-28.28s : %9i -> %9i (%5.1f%%),%7.1f MB/s\n", compressorName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / bestTime / 1000.);

            totalCTime[cAlgNb] += bestTime;
            totalCSize[cAlgNb] += cSize;
        }

        // Prepare layout for decompression
        for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
        {
            chunkP[chunkNb].compressedSize = LZ4_compress(chunkP[chunkNb].origBuffer, chunkP[chunkNb].compressedBuffer, chunkP[chunkNb].origSize);
            if (chunkP[chunkNb].compressedSize==0) DISPLAY("ERROR ! %s() = 0 !! \n", "LZ4_compress"), exit(1);
        }
        { size_t i; for (i=0; i<benchedSize; i++) orig_buff[i]=0; }     // zeroing source area, for CRC checking

        // Decompression Algorithms
        for (dAlgNb=0; (dAlgNb < NB_DECOMPRESSION_ALGORITHMS) && (decompressionTest); dAlgNb++)
        {
            char* dName = decompressionNames[dAlgNb];
            int (*decompressionFunction)(const char*, char*, int, int);
            double bestTime = 100000000.;

            if ((decompressionAlgo != ALL_DECOMPRESSORS) && (decompressionAlgo != dAlgNb+1)) continue;

            switch(dAlgNb)
            {
            case 0: decompressionFunction = local_LZ4_decompress_fast; break;
            case 1: decompressionFunction = local_LZ4_decompress_fast_withPrefix64k; break;
            case 2: decompressionFunction = local_LZ4_decompress_fast_usingDict; break;
            case 3: decompressionFunction = LZ4_decompress_safe; break;
            case 4: decompressionFunction = LZ4_decompress_safe_withPrefix64k; break;
            case 5: decompressionFunction = local_LZ4_decompress_safe_usingDict; break;
            case 6: decompressionFunction = local_LZ4_decompress_safe_partial; break;
            default : DISPLAY("ERROR ! Bad decompression algorithm Id !! \n"); free(chunkP); return 1;
            }

            for (loopNb = 1; loopNb <= nbIterations; loopNb++)
            {
                double averageTime;
                int milliTime;
                U32 crcDecoded;

                PROGRESS("%1i-%-29.29s :%10i ->\r", loopNb, dName, (int)benchedSize);

                nb_loops = 0;
                milliTime = BMK_GetMilliStart();
                while(BMK_GetMilliStart() == milliTime);
                milliTime = BMK_GetMilliStart();
                while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
                {
                    for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
                    {
                        int decodedSize = decompressionFunction(chunkP[chunkNb].compressedBuffer, chunkP[chunkNb].origBuffer, chunkP[chunkNb].compressedSize, chunkP[chunkNb].origSize);
                        if (chunkP[chunkNb].origSize != decodedSize) DISPLAY("ERROR ! %s() == %i != %i !! \n", dName, decodedSize, chunkP[chunkNb].origSize), exit(1);
                    }
                    nb_loops++;
                }
                milliTime = BMK_GetMilliSpan(milliTime);

                averageTime = (double)milliTime / nb_loops;
                if (averageTime < bestTime) bestTime = averageTime;

                PROGRESS("%1i-%-29.29s :%10i -> %7.1f MB/s\r", loopNb, dName, (int)benchedSize, (double)benchedSize / bestTime / 1000.);

                // CRC Checking
                crcDecoded = XXH32(orig_buff, (int)benchedSize, 0);
                if (crcOriginal!=crcDecoded) { DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", inFileName, (unsigned)crcOriginal, (unsigned)crcDecoded); exit(1); }
            }

            DISPLAY("%-31.31s :%10i -> %7.1f MB/s\n", dName, (int)benchedSize, (double)benchedSize / bestTime / 1000.);

            totalDTime[dAlgNb] += bestTime;
        }

      }

      free(orig_buff);
      free(compressed_buff);
      free(chunkP);
  }

  if (BMK_pause) { printf("press enter...\n"); getchar(); }

  return 0;
}


static int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); }


int LZ4IO_setBlockMode(blockMode_t blockMode)
{
    blockIndependence = (blockMode == independentBlocks);
    return blockIndependence;
}


int LZ4_NbCommonBytes (register U32 val)
{
# if defined(LZ4_BIG_ENDIAN)
#   if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
    unsigned long r = 0;
    _BitScanReverse( &r, val );
    return (int)(r>>3);
#   elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
    return (__builtin_clz(val) >> 3);
#   else
    int r;
    if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
    r += (!val);
    return r;
#   endif
# else
#   if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
    unsigned long r;
    _BitScanForward( &r, val );
    return (int)(r>>3);
#   elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
    return (__builtin_ctz(val) >> 3);
#   else
    static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
    return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
#   endif
# endif
}


int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxOutputSize)
{
    return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, noDict, NULL, 0);
}


static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
{
    if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
    if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
    { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; }   /* default, to ensure a return */
}


void* LZ4_createStream()
{
    void* lz4s = ALLOCATOR(4, LZ4_STREAMSIZE_U32);
    MEM_INIT(lz4s, 0, LZ4_STREAMSIZE);
    return lz4s;
}


static inline int get_byte(LZOContext *c)
{
    if (c->in < c->in_end)
        return *c->in++;
    c->error |= AV_LZO_INPUT_DEPLETED;
    return 1;
}


do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
	       IOBUF a, size_t *ret_len )
{
    int zrc;
    int rc = 0;
    int leave = 0;
    size_t n;
    int nread, count;
    int refill = !zs->avail_in;

    if( DBG_FILTER )
	log_debug("begin inflate: avail_in=%u, avail_out=%u, inbuf=%u\n",
		(unsigned)zs->avail_in, (unsigned)zs->avail_out,
		(unsigned)zfx->inbufsize );
    do {
	if( zs->avail_in < zfx->inbufsize && refill ) {
	    n = zs->avail_in;
	    if( !n )
#ifndef __riscos__
		zs->next_in = zfx->inbuf;
#else /* __riscos__ */
		zs->next_in = (Bytef *) zfx->inbuf;
#endif /* __riscos__ */
	    count = zfx->inbufsize - n;
	    nread = iobuf_read( a, zfx->inbuf + n, count );
	    if( nread == -1 )
                nread = 0;
	    n += nread;
	    /* Algo 1 has no zlib header which requires us to to give
	     * inflate an extra dummy byte to read. To be on the safe
	     * side we allow for up to 4 ff bytes.  */
	    if( nread < count && zfx->algo == 1 && zfx->algo1hack < 4) {
		*(zfx->inbuf + n) = 0xFF;
		zfx->algo1hack++;
		n++;
                leave = 1;
	    }
	    zs->avail_in = n;
	}
	refill = 1;
	if( DBG_FILTER )
	    log_debug("enter inflate: avail_in=%u, avail_out=%u\n",
		    (unsigned)zs->avail_in, (unsigned)zs->avail_out);
#ifdef Z_SYNC_FLUSH
	zrc = inflate( zs, Z_SYNC_FLUSH );
#else
	zrc = inflate( zs, Z_PARTIAL_FLUSH );
#endif
	if( DBG_FILTER )
	    log_debug("leave inflate: avail_in=%u, avail_out=%u, zrc=%d\n",
		   (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc);
	if( zrc == Z_STREAM_END )
	    rc = -1; /* eof */
	else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) {
	    if( zs->msg )
		log_fatal("zlib inflate problem: %s\n", zs->msg );
	    else
		log_fatal("zlib inflate problem: rc=%d\n", zrc );
	}
    } while (zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR
             && !leave);
    *ret_len = zfx->outbufsize - zs->avail_out;
    if( DBG_FILTER )
	log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len );
    return rc;
}


do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, IOBUF a )
{
    int rc;
    int zrc;
    unsigned n;

    do {
	zs->next_out = BYTEF_CAST (zfx->outbuf);
	zs->avail_out = zfx->outbufsize;
	if( DBG_FILTER )
	    log_debug("enter deflate: avail_in=%u, avail_out=%u, flush=%d\n",
		    (unsigned)zs->avail_in, (unsigned)zs->avail_out, flush );
	zrc = deflate( zs, flush );
	if( zrc == Z_STREAM_END && flush == Z_FINISH )
	    ;
	else if( zrc != Z_OK ) {
	    if( zs->msg )
		log_fatal("zlib deflate problem: %s\n", zs->msg );
	    else
		log_fatal("zlib deflate problem: rc=%d\n", zrc );
	}
	n = zfx->outbufsize - zs->avail_out;
	if( DBG_FILTER )
	    log_debug("leave deflate: "
		      "avail_in=%u, avail_out=%u, n=%u, zrc=%d\n",
		(unsigned)zs->avail_in, (unsigned)zs->avail_out,
					       (unsigned)n, zrc );

	if( (rc=iobuf_write( a, zfx->outbuf, n )) ) {
	    log_debug("deflate: iobuf_write failed\n");
	    return rc;
	}
    } while( zs->avail_in || (flush == Z_FINISH && zrc != Z_STREAM_END) );
    return 0;
}


   Return the current SAPI module name */
PHP_FUNCTION(php_sapi_name)
{
	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

	if (sapi_module.name) {
		RETURN_STRING(sapi_module.name, 1);
	} else {
		RETURN_FALSE;
	}


*/
static void php_print_gpcse_array(char *name, uint name_length TSRMLS_DC)
{
	zval **data, **tmp, tmp2;
	char *string_key;
	uint string_len;
	ulong num_key;

	zend_is_auto_global(name, name_length TSRMLS_CC);

	if (zend_hash_find(&EG(symbol_table), name, name_length+1, (void **) &data)!=FAILURE
		&& (Z_TYPE_PP(data)==IS_ARRAY)) {
		zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data));
		while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) {
			if (!sapi_module.phpinfo_as_text) {
				php_info_print("
");
				php_info_print("");
			}

			php_info_print(name);
			php_info_print("[\"");

			switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL)) {
				case HASH_KEY_IS_STRING:
					if (!sapi_module.phpinfo_as_text) {
						php_info_print_html_esc(string_key, string_len-1);
					} else {
						php_info_print(string_key);
					}
					break;
				case HASH_KEY_IS_LONG:
					php_info_printf("%ld", num_key);
					break;
			}
			php_info_print("\"]");
			if (!sapi_module.phpinfo_as_text) {
				php_info_print("	");
			} else {
				php_info_print(" => ");
			}
			if (Z_TYPE_PP(tmp) == IS_ARRAY) {
				if (!sapi_module.phpinfo_as_text) {
					php_info_print("
");
					zend_print_zval_r_ex((zend_write_func_t) php_info_print_html_esc, *tmp, 0 TSRMLS_CC);
					php_info_print("
");
				} else {
					zend_print_zval_r(*tmp, 0 TSRMLS_CC);
				}
			} else {
				tmp2 = **tmp;
				if (Z_TYPE_PP(tmp) != IS_STRING) {
					tmp = NULL;
					zval_copy_ctor(&tmp2);
					convert_to_string(&tmp2);
				}

				if (!sapi_module.phpinfo_as_text) {
					if (Z_STRLEN(tmp2) == 0) {
						php_info_print("no value");
					} else {
						php_info_print_html_esc(Z_STRVAL(tmp2), Z_STRLEN(tmp2));
					}
				} else {
					php_info_print(Z_STRVAL(tmp2));
				}

				if (!tmp) {
					zval_dtor(&tmp2);
				}
			}
			if (!sapi_module.phpinfo_as_text) {
				php_info_print("
\n");
			} else {
				php_info_print("\n");
			}
			zend_hash_move_forward(Z_ARRVAL_PP(data));
		}
	}


*/
static void php_info_print_table_row_internal(int num_cols,
		const char *value_class, va_list row_elements)
{
	int i;
	char *row_element;

	if (!sapi_module.phpinfo_as_text) {
		php_info_print("
");
	}
	for (i=0; i<num_cols; i++) {
		if (!sapi_module.phpinfo_as_text) {
			php_info_printf("",
			   (i==0 ? "e" : value_class )
			);
		}
		row_element = va_arg(row_elements, char *);
		if (!row_element || !*row_element) {
			if (!sapi_module.phpinfo_as_text) {
				php_info_print( "no value" );
			} else {
				php_info_print( " " );
			}
		} else {
			if (!sapi_module.phpinfo_as_text) {
				php_info_print_html_esc(row_element, strlen(row_element));
			} else {
				php_info_print(row_element);
				if (i < num_cols-1) {
					php_info_print(" => ");
				}
			}
		}
		if (!sapi_module.phpinfo_as_text) {
			php_info_print(" 	");
		} else if (i == (num_cols - 1)) {
			php_info_print("\n");
		}
	}
	if (!sapi_module.phpinfo_as_text) {
		php_info_print("
\n");
	}


static void *spl_ptr_llist_first(spl_ptr_llist *llist) /* {{{ */
{
	spl_ptr_llist_element *head = llist->head;

	if (head == NULL) {
		return NULL;
	} else {
		return head->data;
	}
}


SPL_METHOD(SplDoublyLinkedList, add)
{
	zval                  *zindex, *value;
	spl_dllist_object     *intern;
	spl_ptr_llist_element *element;
	long                  index;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) {
		return;
	}

	intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
	index  = spl_offset_convert_to_long(zindex TSRMLS_CC);

	if (index < 0 || index > intern->llist->count) {
		zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
		return;
	}

	Z_ADDREF_P(value);
	if (index == intern->llist->count) {
		/* If index is the last entry+1 then we do a push because we're not inserting before any entry */
		spl_ptr_llist_push(intern->llist, value TSRMLS_CC);
	} else {
		/* Create the new element we want to insert */
		spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element));

		/* Get the element we want to insert before */
		element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);

		elem->data = value;
		elem->rc   = 1;
		/* connect to the neighbours */
		elem->next = element;
		elem->prev = element->prev;

		/* connect the neighbours to this new element */
		if (elem->prev == NULL) {
			intern->llist->head = elem;
		} else {
			element->prev->next = elem;
		}
		element->prev = elem;

		intern->llist->count++;

		if (intern->llist->ctor) {
			intern->llist->ctor(elem TSRMLS_CC);
		}
	}
} /* }}} */


static void spl_dllist_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
	spl_dllist_it *iterator = (spl_dllist_it *)iter;

	ZVAL_LONG(key, iterator->traverse_position);
}


static void spl_dllist_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
{
	spl_dllist_it *iterator = (spl_dllist_it *)iter;

	SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);

	zend_user_it_invalidate_current(iter TSRMLS_CC);
	zval_ptr_dtor((zval**)&iterator->intern.it.data);

	efree(iterator);
}


static void *spl_ptr_llist_last(spl_ptr_llist *llist) /* {{{ */
{
	spl_ptr_llist_element *tail = llist->tail;

	if (tail == NULL) {
		return NULL;
	} else {
		return tail->data;
	}
}


int main(int argc, uschar **argv)
{
int i;
uschar buffer[1024];

debug_selector = D_v;
debug_file = stderr;
debug_fd = fileno(debug_file);
big_buffer = malloc(big_buffer_size);

for (i = 1; i < argc; i++)
  {
  if (argv[i][0] == '+')
    {
    debug_trace_memory = 2;
    argv[i]++;
    }
  if (isdigit(argv[i][0]))
    debug_selector = Ustrtol(argv[i], NULL, 0);
  else
    if (Ustrspn(argv[i], "abcdefghijklmnopqrtsuvwxyz0123456789-.:/") ==
        Ustrlen(argv[i]))
      {
      #ifdef LOOKUP_LDAP
      eldap_default_servers = argv[i];
      #endif
      #ifdef LOOKUP_MYSQL
      mysql_servers = argv[i];
      #endif
      #ifdef LOOKUP_PGSQL
      pgsql_servers = argv[i];
      #endif
      #ifdef EXPERIMENTAL_REDIS
      redis_servers = argv[i];
      #endif
      }
  #ifdef EXIM_PERL
  else opt_perl_startup = argv[i];
  #endif
  }

printf("Testing string expansion: debug_level = %d\n\n", debug_level);

expand_nstring[1] = US"string 1....";
expand_nlength[1] = 8;
expand_nmax = 1;

#ifdef EXIM_PERL
if (opt_perl_startup != NULL)
  {
  uschar *errstr;
  printf("Starting Perl interpreter\n");
  errstr = init_perl(opt_perl_startup);
  if (errstr != NULL)
    {
    printf("** error in perl_startup code: %s\n", errstr);
    return EXIT_FAILURE;
    }
  }
#endif /* EXIM_PERL */

while (fgets(buffer, sizeof(buffer), stdin) != NULL)
  {
  void *reset_point = store_get(0);
  uschar *yield = expand_string(buffer);
  if (yield != NULL)
    {
    printf("%s\n", yield);
    store_reset(reset_point);
    }
  else
    {
    if (search_find_defer) printf("search_find deferred\n");
    printf("Failed: %s\n", expand_string_message);
    if (expand_string_forcedfail) printf("Forced failure\n");
    printf("\n");
    }
  }

search_tidyup();

return 0;
}


eval_op_and(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
int_eximarith_t x = eval_op_shift(&s, decimal, error);
if (*error == NULL)
  {
  while (*s == '&')
    {
    int_eximarith_t y;
    s++;
    y = eval_op_shift(&s, decimal, error);
    if (*error != NULL) break;
    x &= y;
    }
  }
*sptr = s;
return x;
}


read_number(int *n, uschar *s)
{
*n = 0;
while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
return s;
}


expand_check_condition(uschar *condition, uschar *m1, uschar *m2)
{
int rc;
uschar *ss = expand_string(condition);
if (ss == NULL)
  {
  if (!expand_string_forcedfail && !search_find_defer)
    log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand condition \"%s\" "
      "for %s %s: %s", condition, m1, m2, expand_string_message);
  return FALSE;
  }
rc = ss[0] != 0 && Ustrcmp(ss, "0") != 0 && strcmpic(ss, US"no") != 0 &&
  strcmpic(ss, US"false") != 0;
return rc;
}


restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
  int *save_expand_nlength)
{
int i;
expand_nmax = save_expand_nmax;
for (i = 0; i <= expand_nmax; i++)
  {
  expand_nstring[i] = save_expand_nstring[i];
  expand_nlength[i] = save_expand_nlength[i];
  }
}


expand_getlistele(int field, uschar * list)
{
uschar * tlist= list;
int sep= 0;
uschar dummy;

if(field<0)
{
  for(field++; string_nextinlist(&tlist, &sep, &dummy, 1); ) field++;
  sep= 0;
}
if(field==0) return NULL;
while(--field>0 && (string_nextinlist(&list, &sep, &dummy, 1))) ;
return string_nextinlist(&list, &sep, NULL, 0);
}


chop_match(uschar *name, uschar **table, int table_size)
{
uschar **bot = table;
uschar **top = table + table_size;

while (top > bot)
  {
  uschar **mid = bot + (top - bot)/2;
  int c = Ustrcmp(name, *mid);
  if (c == 0) return mid - table;
  if (c > 0) bot = mid + 1; else top = mid;
  }

return -1;
}


mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p,
         mpi_ptr_t rp, mpi_size_t rsize,
         mpi_ptr_t sp, mpi_size_t ssize,
         mpi_ptr_t mp, mpi_size_t msize,
         struct karatsuba_ctx *karactx_p)
{
  if( ssize < KARATSUBA_THRESHOLD )
    mpihelp_mul ( xp, rp, rsize, sp, ssize );
  else
    mpihelp_mul_karatsuba_case (xp, rp, rsize, sp, ssize, karactx_p);

   if (rsize + ssize > msize)
    {
      mpihelp_divrem (xp + msize, 0, xp, rsize + ssize, mp, msize);
      *xsize_p = msize;
    }
   else
     *xsize_p = rsize + ssize;
}


bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags)
{
	pid_t child;

	child = fork();
	if (child == -1) {
		die("fork failed: %s\n",
			strerror(errno));
	}
	if (child != 0) { /* parent */
		pid_t pid;
		int status;
		pid = waitpid(child, &status, 0);
		if (pid == -1) {
			die("waitpid failed: %s\n",
				strerror(errno));
		}
		if (pid != child) {
			die("waited for %d got %d\n",
				child, pid);
		}
		if (!WIFEXITED(status)) {
			die("child did not terminate cleanly\n");
		}
		return WEXITSTATUS(status) == EXIT_SUCCESS ? true : false;
	}

	create_and_enter_userns();
	if (unshare(CLONE_NEWNS) != 0) {
		die("unshare(CLONE_NEWNS) failed: %s\n",
			strerror(errno));
	}

	if (mount("testing", "/tmp", "ramfs", mount_flags, NULL) != 0) {
		die("mount of /tmp failed: %s\n",
			strerror(errno));
	}

	create_and_enter_userns();

	if (unshare(CLONE_NEWNS) != 0) {
		die("unshare(CLONE_NEWNS) failed: %s\n",
			strerror(errno));
	}

	if (mount("/tmp", "/tmp", "none",
		  MS_REMOUNT | MS_BIND | remount_flags, NULL) != 0) {
		/* system("cat /proc/self/mounts"); */
		die("remount of /tmp failed: %s\n",
		    strerror(errno));
	}

	if (mount("/tmp", "/tmp", "none",
		  MS_REMOUNT | MS_BIND | invalid_flags, NULL) == 0) {
		/* system("cat /proc/self/mounts"); */
		die("remount of /tmp with invalid flags "
		    "succeeded unexpectedly\n");
	}
	exit(EXIT_SUCCESS);
}


static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			Z_ADDREF_P(expr_ptr);
		} else
#endif
		if (IS_CV == IS_CONST || PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			Z_ADDREF_P(expr_ptr);
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), zend_dval_to_lval(Z_DVAL_P(offset)), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		zval_dtor(free_op2.var);
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_PRINT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	return ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


static int ZEND_FASTCALL  ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_PRINT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	return ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


PHP_FUNCTION(imagepstext)
{
	zval *img, *fnt;
	int i, j;
	long _fg, _bg, x, y, size, space = 0, aa_steps = 4, width = 0;
	int *f_ind;
	int h_lines, v_lines, c_ind;
	int rd, gr, bl, fg_rd, fg_gr, fg_bl, bg_rd, bg_gr, bg_bl;
	int fg_al, bg_al, al;
	int aa[16];
	int amount_kern, add_width;
	double angle = 0.0, extend;
	unsigned long aa_greys[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
	gdImagePtr bg_img;
	GLYPH *str_img;
	T1_OUTLINE *char_path, *str_path;
	T1_TMATRIX *transform = NULL;
	char *str;
	int str_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrlllll|lldl", &img, &str, &str_len, &fnt, &size, &_fg, &_bg, &x, &y, &space, &width, &angle, &aa_steps) == FAILURE) {
		return;
	}

	ZEND_FETCH_RESOURCE(bg_img, gdImagePtr, &img, -1, "Image", le_gd);
	ZEND_FETCH_RESOURCE(f_ind, int *, &fnt, -1, "Type 1 font", le_ps_font);

	/* Ensure that the provided colors are valid */
	if (_fg < 0 || (!gdImageTrueColor(bg_img) && _fg > gdImageColorsTotal(bg_img))) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Foreground color index %ld out of range", _fg);
		RETURN_FALSE;
	}

	if (_bg < 0 || (!gdImageTrueColor(bg_img) && _fg > gdImageColorsTotal(bg_img))) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Background color index %ld out of range", _bg);
		RETURN_FALSE;
	}

	fg_rd = gdImageRed  (bg_img, _fg);
	fg_gr = gdImageGreen(bg_img, _fg);
	fg_bl = gdImageBlue (bg_img, _fg);
	fg_al = gdImageAlpha(bg_img, _fg);

	bg_rd = gdImageRed  (bg_img, _bg);
	bg_gr = gdImageGreen(bg_img, _bg);
	bg_bl = gdImageBlue (bg_img, _bg);
	bg_al = gdImageAlpha(bg_img, _bg);

	for (i = 0; i < aa_steps; i++) {
		rd = bg_rd + (double) (fg_rd - bg_rd) / aa_steps * (i + 1);
		gr = bg_gr + (double) (fg_gr - bg_gr) / aa_steps * (i + 1);
		bl = bg_bl + (double) (fg_bl - bg_bl) / aa_steps * (i + 1);
		al = bg_al + (double) (fg_al - bg_al) / aa_steps * (i + 1);
		aa[i] = gdImageColorResolveAlpha(bg_img, rd, gr, bl, al);
	}

	T1_AASetBitsPerPixel(8);

	switch (aa_steps) {
		case 4:
			T1_AASetGrayValues(0, 1, 2, 3, 4);
			T1_AASetLevel(T1_AA_LOW);
			break;
		case 16:
			T1_AAHSetGrayValues(aa_greys);
			T1_AASetLevel(T1_AA_HIGH);
			break;
		default:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value %ld as number of steps for antialiasing", aa_steps);
			RETURN_FALSE;
	}

	if (angle) {
		transform = T1_RotateMatrix(NULL, angle);
	}

	if (width) {
		extend = T1_GetExtend(*f_ind);
		str_path = T1_GetCharOutline(*f_ind, str[0], size, transform);

		if (!str_path) {
			if (T1_errno) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno));
			}
			RETURN_FALSE;
		}

		for (i = 1; i < str_len; i++) {
			amount_kern = (int) T1_GetKerning(*f_ind, str[i - 1], str[i]);
			amount_kern += str[i - 1] == ' ' ? space : 0;
			add_width = (int) (amount_kern + width) / extend;

			char_path = T1_GetMoveOutline(*f_ind, add_width, 0, 0, size, transform);
			str_path = T1_ConcatOutlines(str_path, char_path);

			char_path = T1_GetCharOutline(*f_ind, str[i], size, transform);
			str_path = T1_ConcatOutlines(str_path, char_path);
		}
		str_img = T1_AAFillOutline(str_path, 0);
	} else {
		str_img = T1_AASetString(*f_ind, str,  str_len, space, T1_KERNING, size, transform);
	}
	if (T1_errno) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "T1Lib Error: %s", T1_StrError(T1_errno));
		RETURN_FALSE;
	}

	h_lines = str_img->metrics.ascent -  str_img->metrics.descent;
	v_lines = str_img->metrics.rightSideBearing - str_img->metrics.leftSideBearing;

	for (i = 0; i < v_lines; i++) {
		for (j = 0; j < h_lines; j++) {
			switch (str_img->bits[j * v_lines + i]) {
				case 0:
					break;
				default:
					c_ind = aa[str_img->bits[j * v_lines + i] - 1];
					gdImageSetPixel(bg_img, x + str_img->metrics.leftSideBearing + i, y - str_img->metrics.ascent + j, c_ind);
					break;
			}
		}
	}

	array_init(return_value);

	add_next_index_long(return_value, str_img->metrics.leftSideBearing);
	add_next_index_long(return_value, str_img->metrics.descent);
	add_next_index_long(return_value, str_img->metrics.rightSideBearing);
	add_next_index_long(return_value, str_img->metrics.ascent);
}


static int ZEND_FASTCALL  ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	compare_function(result,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_VAR != IS_VAR || container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						zend_hash_index_del(ht, zend_dval_to_lval(Z_DVAL_P(offset)));
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						zend_hash_index_del(ht, Z_LVAL_P(offset));
						break;
					case IS_STRING:
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							Z_ADDREF_P(offset);
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				zval_dtor(free_op2.var);
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (1) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (1) {
					zval_ptr_dtor(&offset);
				} else {
					zval_dtor(free_op2.var);
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				zval_dtor(free_op2.var);
				break;
		}
	} else {
		zval_dtor(free_op2.var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (IS_CV != IS_VAR || container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (Z_OBJ_HT_P(*container)->unset_property) {
				Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			} else {
				zend_error(E_NOTICE, "Trying to unset property of non-object");
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **container;

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		if (IS_CV == IS_VAR && !container) {
			zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
		}
		zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_W TSRMLS_CC);
		if (IS_CV == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}
	} else {
		if (IS_TMP_VAR == IS_UNUSED) {
			zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
		}
		container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
		if (IS_CV == IS_VAR && !container) {
			zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
		}
		zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_R TSRMLS_CC);
	}
	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

	if (IS_CONST == IS_CONST) {
		/* no function found. try a static method in class */
		ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC);
		if (!ce) {
			zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL(opline->op1.u.constant));
		}
		EX(called_scope) = ce;
	} else {
		ce = EX_T(opline->op1.u.var).class_entry;

		if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
			EX(called_scope) = EG(called_scope);
		} else {
			EX(called_scope) = ce;
		}
	}
	if(IS_UNUSED != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen = 0;

		if (IS_UNUSED == IS_CONST) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = NULL;

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
 			}
		}

		if (function_name_strval) {
			if (ce->get_static_method) {
				EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
			} else {
				EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
			}
			if (!EX(fbc)) {
				zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
			}
		}

		if (IS_UNUSED != IS_CONST) {

		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Cannot call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			Z_ADDREF_P(EX(object));
			EX(called_scope) = Z_OBJCE_P(EX(object));
		}
	}

	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(sqlite_last_error)
{
	zval *zdb;
	struct php_sqlite_db *db;
	zval *object = getThis();

	if (object) {
		if (zend_parse_parameters_none() == FAILURE) {
			return;
		}
		DB_FROM_OBJECT(db, object);
	} else {
		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
			return;
		}
		DB_FROM_ZVAL(db, &zdb);
	}

	RETURN_LONG(db->last_err_code);
}


static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
			PZVAL_LOCK(EG(uninitialized_zval_ptr));
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		zval *retval;

		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result)) {
			if (Z_REFCOUNT_P(retval) == 0) {
				GC_REMOVE_ZVAL_FROM_BUFFER(retval);
				zval_dtor(retval);
				FREE_ZVAL(retval);
			}
		} else {
			AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
			PZVAL_LOCK(retval);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(unlink)
{
	char *filename;
	int filename_len;
	php_stream_wrapper *wrapper;
	zval *zcontext = NULL;
	php_stream_context *context = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &filename, &filename_len, &zcontext) == FAILURE) {
		RETURN_FALSE;
	}

	if (strlen(filename) != filename_len) {
		RETURN_FALSE;
	}

	context = php_stream_context_from_zval(zcontext, 0);

	wrapper = php_stream_locate_url_wrapper(filename, NULL, 0 TSRMLS_CC);

	if (!wrapper || !wrapper->wops) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
		RETURN_FALSE;
	}

	if (!wrapper->wops->unlink) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
		RETURN_FALSE;
	}
	RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC));
}


PHP_FUNCTION(sqlite_num_fields)
{
	zval *zres;
	struct php_sqlite_result *res;
	zval *object = getThis();

	if (object) {
		if (zend_parse_parameters_none() == FAILURE) {
			return;
		}
		RES_FROM_OBJECT(res, object);
	} else {
		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
			return;
		}
		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
	}

	RETURN_LONG(res->ncolumns);
}


static int ZEND_FASTCALL  ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);

	if (IS_CV == IS_VAR && !var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (IS_CV == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		Z_ADDREF_P(val);
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
		&& ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
	return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


PHP_FUNCTION(chdir)
{
	char *str;
	int ret, str_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
		RETURN_FALSE;
	}

	if (strlen(str) != str_len) {
		RETURN_FALSE;
	}

	if ((PG(safe_mode) && !php_checkuid(str, NULL, CHECKUID_CHECK_FILE_AND_DIR)) || php_check_open_basedir(str TSRMLS_CC)) {
		RETURN_FALSE;
	}
	ret = VCWD_CHDIR(str);

	if (ret != 0) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
		RETURN_FALSE;
	}

	if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) {
		efree(BG(CurrentStatFile));
		BG(CurrentStatFile) = NULL;
	}
	if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) {
		efree(BG(CurrentLStatFile));
		BG(CurrentLStatFile) = NULL;
	}

	RETURN_TRUE;
}


static int ZEND_FASTCALL  ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(fputcsv)
{
	char delimiter = ',';	/* allow this to be set as parameter */
	char enclosure = '"';	/* allow this to be set as parameter */
	const char escape_char = '\\';
	php_stream *stream;
	int ret;
	zval *fp = NULL, *fields = NULL, **field_tmp = NULL, field;
	char *delimiter_str = NULL, *enclosure_str = NULL;
	int delimiter_str_len = 0, enclosure_str_len = 0;
	HashPosition pos;
	int count, i = 0;
	smart_str csvline = {0};

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ss",
			&fp, &fields, &delimiter_str, &delimiter_str_len,
			&enclosure_str, &enclosure_str_len) == FAILURE) {
		return;
	}

	if (delimiter_str != NULL) {
		/* Make sure that there is at least one character in string */
		if (delimiter_str_len < 1) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
			RETURN_FALSE;
		} else if (delimiter_str_len > 1) {
			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
		}

		/* use first character from string */
		delimiter = *delimiter_str;
	}

	if (enclosure_str != NULL) {
		if (enclosure_str_len < 1) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
			RETURN_FALSE;
		} else if (enclosure_str_len > 1) {
			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
		}
		/* use first character from string */
		enclosure = *enclosure_str;
	}

	PHP_STREAM_TO_ZVAL(stream, &fp);

	count = zend_hash_num_elements(Z_ARRVAL_P(fields));
	zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
	while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field_tmp, &pos) == SUCCESS) {
		field = **field_tmp;

		if (Z_TYPE_PP(field_tmp) != IS_STRING) {
			zval_copy_ctor(&field);
			convert_to_string(&field);
		}

		/* enclose a field that contains a delimiter, an enclosure character, or a newline */
		if (FPUTCSV_FLD_CHK(delimiter) ||
			FPUTCSV_FLD_CHK(enclosure) ||
			FPUTCSV_FLD_CHK(escape_char) ||
			FPUTCSV_FLD_CHK('\n') ||
			FPUTCSV_FLD_CHK('\r') ||
			FPUTCSV_FLD_CHK('\t') ||
			FPUTCSV_FLD_CHK(' ')
		) {
			char *ch = Z_STRVAL(field);
			char *end = ch + Z_STRLEN(field);
			int escaped = 0;

			smart_str_appendc(&csvline, enclosure);
			while (ch < end) {
				if (*ch == escape_char) {
					escaped = 1;
				} else if (!escaped && *ch == enclosure) {
					smart_str_appendc(&csvline, enclosure);
				} else {
					escaped = 0;
				}
				smart_str_appendc(&csvline, *ch);
				ch++;
			}
			smart_str_appendc(&csvline, enclosure);
		} else {
			smart_str_appendl(&csvline, Z_STRVAL(field), Z_STRLEN(field));
		}

		if (++i != count) {
			smart_str_appendl(&csvline, &delimiter, 1);
		}
		zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);

		if (Z_TYPE_PP(field_tmp) != IS_STRING) {
			zval_dtor(&field);
		}
	}

	smart_str_appendc(&csvline, '\n');
	smart_str_0(&csvline);

	if (!PG(magic_quotes_runtime)) {
		ret = php_stream_write(stream, csvline.c, csvline.len);
	} else {
		char *buffer = estrndup(csvline.c, csvline.len);
		int len = csvline.len;
		php_stripslashes(buffer, &len TSRMLS_CC);
		ret = php_stream_write(stream, buffer, len);
		efree(buffer);
	}

	smart_str_free(&csvline);

	RETURN_LONG(ret);
}


static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_TMP(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


static int ZEND_FASTCALL  ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_VAR != IS_VAR || container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (Z_OBJ_HT_P(*container)->unset_property) {
				Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			} else {
				zend_error(E_NOTICE, "Trying to unset property of non-object");
			}
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else {
			zval_dtor(free_op2.var);
		}
	} else {
		zval_dtor(free_op2.var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;
		zend_free_op free_op1;

		value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_vm_stack_push(valptr TSRMLS_CC);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;

		value = &opline->op1.u.constant;

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_vm_stack_push(valptr TSRMLS_CC);

	}
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varptr;

	if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
		if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
			return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
		}
	} else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	if (IS_CV == IS_VAR &&
		(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
		EX_T(opline->op1.u.var).var.fcall_returned_reference &&
		EX_T(opline->op1.u.var).var.ptr) {
		varptr = EX_T(opline->op1.u.var).var.ptr;
		PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
	} else {
		varptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
	if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
	     EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
	    varptr != &EG(uninitialized_zval) &&
	    (PZVAL_IS_REF(varptr) ||
	     (Z_REFCOUNT_P(varptr) == 1 && (IS_CV == IS_CV || free_op1.var)))) {
		Z_SET_ISREF_P(varptr);
		Z_ADDREF_P(varptr);
		zend_vm_stack_push(varptr TSRMLS_CC);
	} else {
		zval *valptr;

		if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
			!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
			!ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error(E_STRICT, "Only variables should be passed by reference");
		}
		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, varptr);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_vm_stack_push(valptr TSRMLS_CC);
	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *result = &EX_T(opline->result.u.var).tmp_var;

	compare_function(result,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_UNUSED == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	if (IS_UNUSED == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}
	zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=NULL;

#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			Z_ADDREF_P(expr_ptr);
		} else
#endif
		if (IS_VAR == IS_CONST || PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			Z_ADDREF_P(expr_ptr);
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), zend_dval_to_lval(Z_DVAL_P(offset)), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(sqlite_unbuffered_query)
{
	zval *zdb;
	struct php_sqlite_db *db;
	char *sql;
	int sql_len;
	long mode = PHPSQLITE_BOTH;
	char *errtext = NULL;
	zval *errmsg = NULL;
	zval *object = getThis();

	if (object) {
		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
			return;
		}
		DB_FROM_OBJECT(db, object);
	} else {
		if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
				ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
			return;
		}
		DB_FROM_ZVAL(db, &zdb);
	}

	if (errmsg) {
		zval_dtor(errmsg);
		ZVAL_NULL(errmsg);
	}

	PHP_SQLITE_EMPTY_QUERY;

	/* avoid doing work if we can */
	if (!return_value_used) {
		db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);

		if (db->last_err_code != SQLITE_OK) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
			if (errmsg) {
				ZVAL_STRING(errmsg, errtext, 1);
			}
			sqlite_freemem(errtext);
		}
		return;
	}

	sqlite_query(object, db, sql, sql_len, (int)mode, 0, return_value, NULL, errmsg TSRMLS_CC);
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (IS_VAR == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
	}
	zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_IS TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(chmod)
{
	char *filename;
	int filename_len;
	long mode;
	int ret;
	mode_t imode;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &filename, &filename_len, &mode) == FAILURE) {
		return;
	}

	if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
		RETURN_FALSE;
	}

	if (strlen(filename) != filename_len) {
		RETURN_FALSE;
	}

	/* Check the basedir */
	if (php_check_open_basedir(filename TSRMLS_CC)) {
		RETURN_FALSE;
	}

	imode = (mode_t) mode;
	/* In safe mode, do not allow to setuid files.
	 * Setuiding files could allow users to gain privileges
	 * that safe mode doesn't give them. */

	if (PG(safe_mode)) {
		php_stream_statbuf ssb;
		if (php_stream_stat_path_ex(filename, 0, &ssb, NULL)) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "stat failed for %s", filename);
			RETURN_FALSE;
		}
		if ((imode & 04000) != 0 && (ssb.sb.st_mode & 04000) == 0) {
			imode ^= 04000;
		}
		if ((imode & 02000) != 0 && (ssb.sb.st_mode & 02000) == 0) {
			imode ^= 02000;
		}
		if ((imode & 01000) != 0 && (ssb.sb.st_mode & 01000) == 0) {
			imode ^= 01000;
		}
	}

	ret = VCWD_CHMOD(filename, imode);
	if (ret == -1) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
		RETURN_FALSE;
	}
	RETURN_TRUE;
}


static int ZEND_FASTCALL  ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);

	if (IS_CV == IS_VAR && !var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (IS_CV == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
			PZVAL_LOCK(EG(uninitialized_zval_ptr));
		}

		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		Z_ADDREF_P(val);
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
		PZVAL_LOCK(*var_ptr);
	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op_array *new_op_array=NULL;
	int return_value_used;
	zend_free_op free_op1;
	zval *inc_filename = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval tmp_inc_filename;
	zend_bool failure_retval=0;

	if (inc_filename->type!=IS_STRING) {
		tmp_inc_filename = *inc_filename;
		zval_copy_ctor(&tmp_inc_filename);
		convert_to_string(&tmp_inc_filename);
		inc_filename = &tmp_inc_filename;
	}

	return_value_used = RETURN_VALUE_USED(opline);

	if (Z_LVAL(opline->op2.u.constant) != ZEND_EVAL && strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)) {
		if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE ||
		    Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE) {
			zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
		} else {
			zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
		}
		goto done;
	}

	switch (Z_LVAL(opline->op2.u.constant)) {
		case ZEND_INCLUDE_ONCE:
		case ZEND_REQUIRE_ONCE: {
				zend_file_handle file_handle;
				char *resolved_path;

				resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC);
				if (resolved_path) {
					failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1);
				} else {
					resolved_path = Z_STRVAL_P(inc_filename);
				}

				if (failure_retval) {
					/* do nothing, file already included */
				} else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) {

					if (!file_handle.opened_path) {
						file_handle.opened_path = estrdup(resolved_path);
					}

					if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
						new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
						zend_destroy_file_handle(&file_handle TSRMLS_CC);
					} else {
						zend_file_handle_dtor(&file_handle TSRMLS_CC);
						failure_retval=1;
					}
				} else {
					if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE) {
						zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
					} else {
						zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);
					}
				}
				if (resolved_path != Z_STRVAL_P(inc_filename)) {
					efree(resolved_path);
				}
			}
			break;
		case ZEND_INCLUDE:
		case ZEND_REQUIRE:
			new_op_array = compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
			break;
		case ZEND_EVAL: {
				char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);

				new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
				efree(eval_desc);
			}
			break;
		EMPTY_SWITCH_DEFAULT_CASE()
	}
done:
	if (inc_filename==&tmp_inc_filename) {
		zval_dtor(&tmp_inc_filename);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (new_op_array && !EG(exception)) {
		EX(original_return_value) = EG(return_value_ptr_ptr);
		EG(return_value_ptr_ptr) = return_value_used ? EX_T(opline->result.u.var).var.ptr_ptr : NULL;
		EG(active_op_array) = new_op_array;
		EX_T(opline->result.u.var).var.ptr = NULL;

		EX(current_object) = EX(object);

		EX(function_state).function = (zend_function *) new_op_array;
		EX(object) = NULL;

		if (!EG(active_symbol_table)) {
			zend_rebuild_symbol_table(TSRMLS_C);
		}

		if (zend_execute == execute) {
			EX(call_opline) = opline;
			ZEND_VM_ENTER();
		} else {
			zend_execute(new_op_array TSRMLS_CC);
		}

		EX(function_state).function = (zend_function *) EX(op_array);
		EX(object) = EX(current_object);

		if (return_value_used) {
			if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = 1;
				Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
			}
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(return_value_ptr_ptr) = EX(original_return_value);
		destroy_op_array(new_op_array TSRMLS_CC);
		efree(new_op_array);
		if (EG(exception)) {
			zend_throw_exception_internal(NULL TSRMLS_CC);
		}
	} else {
		if (return_value_used) {
			ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
			INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = failure_retval;
			Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
		}
	}
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_IS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}


static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (Z_REFCOUNT_P(z) == 0) {
					GC_REMOVE_ZVAL_FROM_BUFFER(z);
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			Z_ADDREF_P(z);
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = NULL;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
	}
	zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	/* We are going to assign the result by reference */
	if (opline->extended_value && EX_T(opline->result.u.var).var.ptr_ptr) {
		Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
		SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC);

	if (IS_CV == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
	}
	zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(imagewbmp)
{
#ifdef USE_GD_IOCTX
	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx);
#else
	_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMP);
#endif
}


static int ZEND_FASTCALL  ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	is_identical_function(result,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	Z_LVAL_P(result) = !Z_LVAL_P(result);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_MOD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (IS_CV == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
	}
	zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}


	efree(object);
}

static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers,
							zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC)
{
	PHPTidyObj *intern;
	zval *tmp;

	intern = emalloc(sizeof(PHPTidyObj));
	memset(intern, 0, sizeof(PHPTidyObj));
	zend_object_std_init(&intern->std, class_type TSRMLS_CC);

	zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

	switch(objtype) {
		case is_node:
			break;

		case is_doc:
			tidySetMallocCall(php_tidy_malloc);
			tidySetReallocCall(php_tidy_realloc);
			tidySetFreeCall(php_tidy_free);
			tidySetPanicCall(php_tidy_panic);

			intern->ptdoc = emalloc(sizeof(PHPTidyDoc));
			intern->ptdoc->doc = tidyCreate();
			intern->ptdoc->ref_count = 1;
			intern->ptdoc->errbuf = emalloc(sizeof(TidyBuffer));
			tidyBufInit(intern->ptdoc->errbuf);

			if (tidySetErrorBuffer(intern->ptdoc->doc, intern->ptdoc->errbuf) != 0) {
				tidyBufFree(intern->ptdoc->errbuf);
				efree(intern->ptdoc->errbuf);
				tidyRelease(intern->ptdoc->doc);
				efree(intern->ptdoc);
				efree(intern);
				php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
			}

			tidyOptSetBool(intern->ptdoc->doc, TidyForceOutput, yes);
			tidyOptSetBool(intern->ptdoc->doc, TidyMark, no);

			TIDY_SET_DEFAULT_CONFIG(intern->ptdoc->doc);

			tidy_add_default_properties(intern, is_doc TSRMLS_CC);
			break;

		default:
			break;
	}


static int ZEND_FASTCALL  ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *result = &EX_T(opline->result.u.var).tmp_var;

	compare_function(result,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *container = &opline->op1.u.constant;

	if (Z_TYPE_P(container) != IS_ARRAY) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
			PZVAL_LOCK(EG(uninitialized_zval_ptr));
		}
	} else {

		zval *dim = &opline->op2.u.constant;

		AI_SET_PTR(EX_T(opline->result.u.var).var, *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC));
		SELECTIVE_PZVAL_LOCK(EX_T(opline->result.u.var).var.ptr, &opline->result);

	}
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
	}
	zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_W TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	/* We are going to assign the result by reference */
	if (opline->extended_value && EX_T(opline->result.u.var).var.ptr_ptr) {
		Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
		SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
	}

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	ZEND_VM_NEXT_OPCODE();
}


static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC)
{
	int j, n = res->ncolumns, buffered = res->buffered;
	const char **rowdata, **colnames;

	/* check range of the row */
	if (res->curr_row >= res->nrows) {
		/* no more */
		RETURN_FALSE;
	}
	colnames = (const char**)res->col_names;
	if (res->buffered) {
		rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
	} else {
		rowdata = (const char**)res->table;
	}

	/* now populate the result */
	array_init(return_value);

	for (j = 0; j < n; j++) {
		zval *decoded;
		MAKE_STD_ZVAL(decoded);

		if (rowdata[j] == NULL) {
			ZVAL_NULL(decoded);
		} else if (decode_binary && rowdata[j][0] == '\x01') {
			Z_STRVAL_P(decoded) = emalloc(strlen(rowdata[j]));
			Z_STRLEN_P(decoded) = php_sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
			Z_STRVAL_P(decoded)[Z_STRLEN_P(decoded)] = '\0';
			Z_TYPE_P(decoded) = IS_STRING;
			if (!buffered) {
				efree((char*)rowdata[j]);
				rowdata[j] = NULL;
			}
		} else {
			ZVAL_STRING(decoded, (char*)rowdata[j], buffered);
			if (!buffered) {
				rowdata[j] = NULL;
			}
		}

		if (mode & PHPSQLITE_NUM) {
			if (mode & PHPSQLITE_ASSOC) {
				add_index_zval(return_value, j, decoded);
				Z_ADDREF_P(decoded);
				add_assoc_zval(return_value, (char*)colnames[j], decoded);
			} else {
				add_next_index_zval(return_value, decoded);
			}
		} else {
			add_assoc_zval(return_value, (char*)colnames[j], decoded);
		}
	}

	if (move_next) {
		if (!res->buffered) {
			/* non buffered: fetch next row */
			php_sqlite_fetch(res TSRMLS_CC);
		}
		/* advance the row pointer */
		res->curr_row++;
	}
}


static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op2, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		zval_dtor(free_op2.var);
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
			EX_T(result->u.var).var.ptr_ptr = NULL;
			PZVAL_LOCK(EG(uninitialized_zval_ptr));
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					EX_T(result->u.var).var.ptr = *zptr;
					EX_T(result->u.var).var.ptr_ptr = NULL;
					PZVAL_LOCK(*zptr);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			if (opline->extended_value == ZEND_ASSIGN_OBJ) {
				if (Z_OBJ_HT_P(object)->read_property) {
					z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
				}
			} else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
				if (Z_OBJ_HT_P(object)->read_dimension) {
					z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
				}
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (Z_REFCOUNT_P(z) == 0) {
						GC_REMOVE_ZVAL_FROM_BUFFER(z);
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				Z_ADDREF_P(z);
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				if (opline->extended_value == ZEND_ASSIGN_OBJ) {
					Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
				} else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
					Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					EX_T(result->u.var).var.ptr = z;
					EX_T(result->u.var).var.ptr_ptr = NULL;
					PZVAL_LOCK(z);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
					EX_T(result->u.var).var.ptr_ptr = NULL;
					PZVAL_LOCK(EG(uninitialized_zval_ptr));
				}
			}
		}

		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		FREE_OP(free_op_data1);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_EXIT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if 0 || (IS_CV != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (IS_CV != IS_UNUSED) {

		zval *ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}

	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (IS_VAR == IS_VAR && !variable_ptr_ptr) {
		if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC)) {
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
			}
		} else if (!RETURN_VALUE_UNUSED(&opline->result)) {
			AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
			PZVAL_LOCK(EG(uninitialized_zval_ptr));
		}
	} else {
	 	value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			AI_SET_PTR(EX_T(opline->result.u.var).var, value);
			PZVAL_LOCK(value);
		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	/* zend_assign_to_variable() always takes care of op2, never free it! */
 	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}


PHP_FUNCTION(disk_free_space)
{
	double bytesfree;
	char *path;
	int path_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
		return;
	}

	if (php_check_open_basedir(path TSRMLS_CC)) {
		RETURN_FALSE;
	}

	if (strlen(path) != path_len) {
		RETURN_FALSE;
	}

	if (php_disk_free_space(path, &bytesfree TSRMLS_CC) == SUCCESS) {
		RETURN_DOUBLE(bytesfree);
	}
	RETURN_FALSE;
}


static int ZEND_FASTCALL  ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	is_identical_function(result,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	Z_LVAL_P(result) = !Z_LVAL_P(result);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_FASTCALL  ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}


	tidy_add_default_properties(newobj, is_node TSRMLS_CC);
}

static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC)
{
	char *opt_name = NULL;
	zval **opt_val;
	ulong opt_indx;

	for (zend_hash_internal_pointer_reset(ht_options);
		 zend_hash_get_current_data(ht_options, (void **)&opt_val) == SUCCESS;
		 zend_hash_move_forward(ht_options)) {

		if(zend_hash_get_current_key(ht_options, &opt_name, &opt_indx, FALSE) == FAILURE) {
			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array");
			return FAILURE;
		}

		if(opt_name) {
			_php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC);
			opt_name = NULL;
		}

	}


static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (IS_VAR == IS_VAR && !container) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
	}
	zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}