File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / Zend / zend_execute.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:35 2012 UTC (12 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_17p0, HEAD
php 5.4.3+patches

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | Zend Engine                                                          |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
    6:    +----------------------------------------------------------------------+
    7:    | This source file is subject to version 2.00 of the Zend license,     |
    8:    | that is bundled with this package in the file LICENSE, and is        |
    9:    | available through the world-wide-web at the following url:           |
   10:    | http://www.zend.com/license/2_00.txt.                                |
   11:    | If you did not receive a copy of the Zend license and are unable to  |
   12:    | obtain it through the world-wide-web, please send a note to          |
   13:    | license@zend.com so we can mail you a copy immediately.              |
   14:    +----------------------------------------------------------------------+
   15:    | Authors: Andi Gutmans <andi@zend.com>                                |
   16:    |          Zeev Suraski <zeev@zend.com>                                |
   17:    +----------------------------------------------------------------------+
   18: */
   19: 
   20: /* $Id: zend_execute.c,v 1.1.1.2 2012/05/29 12:34:35 misho Exp $ */
   21: 
   22: #define ZEND_INTENSIVE_DEBUGGING 0
   23: 
   24: #include <stdio.h>
   25: #include <signal.h>
   26: 
   27: #include "zend.h"
   28: #include "zend_compile.h"
   29: #include "zend_execute.h"
   30: #include "zend_API.h"
   31: #include "zend_ptr_stack.h"
   32: #include "zend_constants.h"
   33: #include "zend_extensions.h"
   34: #include "zend_ini.h"
   35: #include "zend_exceptions.h"
   36: #include "zend_interfaces.h"
   37: #include "zend_closures.h"
   38: #include "zend_vm.h"
   39: #include "zend_dtrace.h"
   40: 
   41: /* Virtual current working directory support */
   42: #include "tsrm_virtual_cwd.h"
   43: 
   44: #define _CONST_CODE  0
   45: #define _TMP_CODE    1
   46: #define _VAR_CODE    2
   47: #define _UNUSED_CODE 3
   48: #define _CV_CODE     4
   49: 
   50: typedef int (*incdec_t)(zval *);
   51: 
   52: #define get_zval_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
   53: #define get_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
   54: #define get_obj_zval_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
   55: #define get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
   56: 
   57: /* Prototypes */
   58: static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
   59: static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
   60: static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
   61: 
   62: #define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
   63: 
   64: #define T(offset) (*(temp_variable *)((char *) Ts + offset))
   65: #define CV(var)   CVs[var]
   66: 
   67: #define TEMP_VAR_STACK_LIMIT 2000
   68: 
   69: static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free, int unref TSRMLS_DC)
   70: {
   71: 	if (!Z_DELREF_P(z)) {
   72: 		Z_SET_REFCOUNT_P(z, 1);
   73: 		Z_UNSET_ISREF_P(z);
   74: 		should_free->var = z;
   75: /*		should_free->is_var = 1; */
   76: 	} else {
   77: 		should_free->var = 0;
   78: 		if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) {
   79: 			Z_UNSET_ISREF_P(z);
   80: 		}
   81: 		GC_ZVAL_CHECK_POSSIBLE_ROOT(z);
   82: 	}
   83: }
   84: 
   85: static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
   86: {
   87: 	if (!Z_DELREF_P(z)) {
   88: 		if (z != &EG(uninitialized_zval)) {
   89: 			GC_REMOVE_ZVAL_FROM_BUFFER(z);
   90: 			zval_dtor(z);
   91: 			efree(z);
   92: 		}
   93: 	}
   94: }
   95: 
   96: #undef zval_ptr_dtor
   97: #define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv)  ZEND_FILE_LINE_CC)
   98: 
   99: #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC)
  100: #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)
  101: #define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC)
  102: #define PZVAL_LOCK(z) Z_ADDREF_P((z))
  103: #define SELECTIVE_PZVAL_LOCK(pzv, opline)	if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
  104: 
  105: #define EXTRACT_ZVAL_PTR(t) do {						\
  106: 		temp_variable *__t = (t);					\
  107: 		if (__t->var.ptr_ptr) {						\
  108: 			__t->var.ptr = *__t->var.ptr_ptr;		\
  109: 			__t->var.ptr_ptr = &__t->var.ptr;		\
  110: 			if (!PZVAL_IS_REF(__t->var.ptr) && 		\
  111: 			    Z_REFCOUNT_P(__t->var.ptr) > 2) {	\
  112: 				SEPARATE_ZVAL(__t->var.ptr_ptr);	\
  113: 			}										\
  114: 		}											\
  115: 	} while (0)
  116: 
  117: #define AI_SET_PTR(t, val) do {				\
  118: 		temp_variable *__t = (t);			\
  119: 		__t->var.ptr = (val);				\
  120: 		__t->var.ptr_ptr = &__t->var.ptr;	\
  121: 	} while (0)
  122: 
  123: #define FREE_OP(should_free) \
  124: 	if (should_free.var) { \
  125: 		if ((zend_uintptr_t)should_free.var & 1L) { \
  126: 			zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \
  127: 		} else { \
  128: 			zval_ptr_dtor(&should_free.var); \
  129: 		} \
  130: 	}
  131: 
  132: #define FREE_OP_IF_VAR(should_free) \
  133: 	if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \
  134: 		zval_ptr_dtor(&should_free.var); \
  135: 	}
  136: 
  137: #define FREE_OP_VAR_PTR(should_free) \
  138: 	if (should_free.var) { \
  139: 		zval_ptr_dtor(&should_free.var); \
  140: 	}
  141: 
  142: #define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L)
  143: 
  144: #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)
  145: 
  146: #define MAKE_REAL_ZVAL_PTR(val) \
  147: 	do { \
  148: 		zval *_tmp; \
  149: 		ALLOC_ZVAL(_tmp); \
  150: 		INIT_PZVAL_COPY(_tmp, (val)); \
  151: 		(val) = _tmp; \
  152: 	} while (0)
  153: 
  154: /* End of zend_execute_locks.h */
  155: 
  156: #define CV_OF(i)     (EG(current_execute_data)->CVs[i])
  157: #define CV_DEF_OF(i) (EG(active_op_array)->vars[i])
  158: 
  159: #define CTOR_CALL_BIT    0x1
  160: #define CTOR_USED_BIT    0x2
  161: 
  162: #define IS_CTOR_CALL(ce) (((zend_uintptr_t)(ce)) & CTOR_CALL_BIT)
  163: #define IS_CTOR_USED(ce) (((zend_uintptr_t)(ce)) & CTOR_USED_BIT)
  164: 
  165: #define ENCODE_CTOR(ce, used) \
  166: 	((zend_class_entry*)(((zend_uintptr_t)(ce)) | CTOR_CALL_BIT | ((used) ? CTOR_USED_BIT : 0)))
  167: #define DECODE_CTOR(ce) \
  168: 	((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT)))
  169: 
  170: ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var)
  171: {
  172: 	return execute_data_ptr->CVs[var];
  173: }
  174: 
  175: static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
  176: {
  177: 	return should_free->var = &T(var).tmp_var;
  178: }
  179: 
  180: static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
  181: {
  182: 	zval *ptr = T(var).var.ptr;
  183: 
  184: 	PZVAL_UNLOCK(ptr, should_free);
  185: 	return ptr;
  186: }
  187: 
  188: static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)
  189: {
  190: 	zend_compiled_variable *cv = &CV_DEF_OF(var);
  191: 
  192: 	if (!EG(active_symbol_table) ||
  193: 	    zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
  194: 		switch (type) {
  195: 			case BP_VAR_R:
  196: 			case BP_VAR_UNSET:
  197: 				zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
  198: 				/* break missing intentionally */
  199: 			case BP_VAR_IS:
  200: 				return &EG(uninitialized_zval_ptr);
  201: 				break;
  202: 			case BP_VAR_RW:
  203: 				zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
  204: 				/* break missing intentionally */
  205: 			case BP_VAR_W:
  206: 				Z_ADDREF(EG(uninitialized_zval));
  207: 				if (!EG(active_symbol_table)) {
  208: 					*ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
  209: 					**ptr = &EG(uninitialized_zval);
  210: 				} else {
  211: 					zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
  212: 				}
  213: 				break;
  214: 		}
  215: 	}
  216: 	return *ptr;
  217: }
  218: 
  219: static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_R(zval ***ptr, zend_uint var TSRMLS_DC)
  220: {
  221: 	zend_compiled_variable *cv = &CV_DEF_OF(var);
  222: 
  223: 	if (!EG(active_symbol_table) ||
  224: 	    zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
  225: 		zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
  226: 		return &EG(uninitialized_zval_ptr);
  227: 	}
  228: 	return *ptr;
  229: }
  230: 
  231: static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_UNSET(zval ***ptr, zend_uint var TSRMLS_DC)
  232: {
  233: 	zend_compiled_variable *cv = &CV_DEF_OF(var);
  234: 
  235: 	if (!EG(active_symbol_table) ||
  236: 	    zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
  237: 		zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
  238: 		return &EG(uninitialized_zval_ptr);
  239: 	}
  240: 	return *ptr;
  241: }
  242: 
  243: static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_IS(zval ***ptr, zend_uint var TSRMLS_DC)
  244: {
  245: 	zend_compiled_variable *cv = &CV_DEF_OF(var);
  246: 
  247: 	if (!EG(active_symbol_table) ||
  248: 	    zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
  249: 		return &EG(uninitialized_zval_ptr);
  250: 	}
  251: 	return *ptr;
  252: }
  253: 
  254: static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_RW(zval ***ptr, zend_uint var TSRMLS_DC)
  255: {
  256: 	zend_compiled_variable *cv = &CV_DEF_OF(var);
  257: 
  258: 	if (!EG(active_symbol_table)) {
  259: 		Z_ADDREF(EG(uninitialized_zval));
  260: 		*ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
  261: 		**ptr = &EG(uninitialized_zval);
  262: 		zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
  263: 	} else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
  264: 		Z_ADDREF(EG(uninitialized_zval));
  265: 		zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
  266: 		zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
  267: 	}
  268: 	return *ptr;
  269: }
  270: 
  271: static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_W(zval ***ptr, zend_uint var TSRMLS_DC)
  272: {
  273: 	zend_compiled_variable *cv = &CV_DEF_OF(var);
  274: 
  275: 	if (!EG(active_symbol_table)) {
  276: 		Z_ADDREF(EG(uninitialized_zval));
  277: 		*ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
  278: 		**ptr = &EG(uninitialized_zval);
  279: 	} else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
  280: 		Z_ADDREF(EG(uninitialized_zval));
  281: 		zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
  282: 	}
  283: 	return *ptr;
  284: }
  285: 
  286: static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC)
  287: {
  288: 	zval ***ptr = &CV_OF(var);
  289: 
  290: 	if (UNEXPECTED(*ptr == NULL)) {
  291: 		return *_get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
  292: 	}
  293: 	return **ptr;
  294: }
  295: 
  296: static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC)
  297: {
  298: 	zval ***ptr = &CV(var);
  299: 
  300: 	if (UNEXPECTED(*ptr == NULL)) {
  301: 		return *_get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
  302: 	}
  303: 	return **ptr;
  304: }
  305: 
  306: static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC)
  307: {
  308: 	zval ***ptr = &CV(var);
  309: 
  310: 	if (UNEXPECTED(*ptr == NULL)) {
  311: 		return *_get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
  312: 	}
  313: 	return **ptr;
  314: }
  315: 
  316: static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC)
  317: {
  318: 	zval ***ptr = &CV(var);
  319: 
  320: 	if (UNEXPECTED(*ptr == NULL)) {
  321: 		return *_get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
  322: 	}
  323: 	return **ptr;
  324: }
  325: 
  326: static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC)
  327: {
  328: 	zval ***ptr = &CV(var);
  329: 
  330: 	if (UNEXPECTED(*ptr == NULL)) {
  331: 		return *_get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
  332: 	}
  333: 	return **ptr;
  334: }
  335: 
  336: static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC)
  337: {
  338: 	zval ***ptr = &CV(var);
  339: 
  340: 	if (UNEXPECTED(*ptr == NULL)) {
  341: 		return *_get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
  342: 	}
  343: 	return **ptr;
  344: }
  345: 
  346: static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
  347: {
  348: /*	should_free->is_var = 0; */
  349: 	switch (op_type) {
  350: 		case IS_CONST:
  351: 			should_free->var = 0;
  352: 			return node->zv;
  353: 			break;
  354: 		case IS_TMP_VAR:
  355: 			should_free->var = TMP_FREE(&T(node->var).tmp_var);
  356: 			return &T(node->var).tmp_var;
  357: 			break;
  358: 		case IS_VAR:
  359: 			return _get_zval_ptr_var(node->var, Ts, should_free TSRMLS_CC);
  360: 			break;
  361: 		case IS_UNUSED:
  362: 			should_free->var = 0;
  363: 			return NULL;
  364: 			break;
  365: 		case IS_CV:
  366: 			should_free->var = 0;
  367: 			return _get_zval_ptr_cv(node->var, type TSRMLS_CC);
  368: 			break;
  369: 		EMPTY_SWITCH_DEFAULT_CASE()
  370: 	}
  371: 	return NULL;
  372: }
  373: 
  374: static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
  375: {
  376: 	zval** ptr_ptr = T(var).var.ptr_ptr;
  377: 
  378: 	if (EXPECTED(ptr_ptr != NULL)) {
  379: 		PZVAL_UNLOCK(*ptr_ptr, should_free);
  380: 	} else {
  381: 		/* string offset */
  382: 		PZVAL_UNLOCK(T(var).str_offset.str, should_free);
  383: 	}
  384: 	return ptr_ptr;
  385: }
  386: 
  387: static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC)
  388: {
  389: 	zval ***ptr = &CV_OF(var);
  390: 
  391: 	if (UNEXPECTED(*ptr == NULL)) {
  392: 		return _get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
  393: 	}
  394: 	return *ptr;
  395: }
  396: 
  397: static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC)
  398: {
  399: 	zval ***ptr = &CV(var);
  400: 
  401: 	if (UNEXPECTED(*ptr == NULL)) {
  402: 		return _get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
  403: 	}
  404: 	return *ptr;
  405: }
  406: 
  407: static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC)
  408: {
  409: 	zval ***ptr = &CV(var);
  410: 
  411: 	if (UNEXPECTED(*ptr == NULL)) {
  412: 		return _get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
  413: 	}
  414: 	return *ptr;
  415: }
  416: 
  417: static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC)
  418: {
  419: 	zval ***ptr = &CV(var);
  420: 
  421: 	if (UNEXPECTED(*ptr == NULL)) {
  422: 		return _get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
  423: 	}
  424: 	return *ptr;
  425: }
  426: 
  427: static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC)
  428: {
  429: 	zval ***ptr = &CV(var);
  430: 
  431: 	if (UNEXPECTED(*ptr == NULL)) {
  432: 		return _get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
  433: 	}
  434: 	return *ptr;
  435: }
  436: 
  437: static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC)
  438: {
  439: 	zval ***ptr = &CV(var);
  440: 
  441: 	if (UNEXPECTED(*ptr == NULL)) {
  442: 		return _get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
  443: 	}
  444: 	return *ptr;
  445: }
  446: 
  447: static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
  448: {
  449: 	if (op_type == IS_CV) {
  450: 		should_free->var = 0;
  451: 		return _get_zval_ptr_ptr_cv(node->var, type TSRMLS_CC);
  452: 	} else if (op_type == IS_VAR) {
  453: 		return _get_zval_ptr_ptr_var(node->var, Ts, should_free TSRMLS_CC);
  454: 	} else {
  455: 		should_free->var = 0;
  456: 		return NULL;
  457: 	}
  458: }
  459: 
  460: static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D)
  461: {
  462: 	if (EXPECTED(EG(This) != NULL)) {
  463: 		return EG(This);
  464: 	} else {
  465: 		zend_error_noreturn(E_ERROR, "Using $this when not in object context");
  466: 		return NULL;
  467: 	}
  468: }
  469: 
  470: static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
  471: {
  472: 	if (op_type == IS_UNUSED) {
  473: 		if (EXPECTED(EG(This) != NULL)) {
  474: 			/* this should actually never be modified, _ptr_ptr is modified only when
  475: 			   the object is empty */
  476: 			should_free->var = 0;
  477: 			return &EG(This);
  478: 		} else {
  479: 			zend_error_noreturn(E_ERROR, "Using $this when not in object context");
  480: 		}
  481: 	}
  482: 	return get_zval_ptr_ptr(op_type, op, Ts, should_free, type);
  483: }
  484: 
  485: static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
  486: {
  487: 	if (EXPECTED(EG(This) != NULL)) {
  488: 		return &EG(This);
  489: 	} else {
  490: 		zend_error_noreturn(E_ERROR, "Using $this when not in object context");
  491: 		return NULL;
  492: 	}
  493: }
  494: 
  495: static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
  496: {
  497: 	if (op_type == IS_UNUSED) {
  498: 		if (EXPECTED(EG(This) != NULL)) {
  499: 			should_free->var = 0;
  500: 			return EG(This);
  501: 		} else {
  502: 			zend_error_noreturn(E_ERROR, "Using $this when not in object context");
  503: 		}
  504: 	}
  505: 	return get_zval_ptr(op_type, op, Ts, should_free, type);
  506: }
  507: 
  508: static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)
  509: {
  510: 	zval *variable_ptr = *variable_ptr_ptr;
  511: 	zval *value_ptr = *value_ptr_ptr;
  512: 
  513: 	if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) {
  514: 		variable_ptr_ptr = &EG(uninitialized_zval_ptr);
  515: 	} else if (variable_ptr != value_ptr) {
  516: 		if (!PZVAL_IS_REF(value_ptr)) {
  517: 			/* break it away */
  518: 			Z_DELREF_P(value_ptr);
  519: 			if (Z_REFCOUNT_P(value_ptr)>0) {
  520: 				ALLOC_ZVAL(*value_ptr_ptr);
  521: 				ZVAL_COPY_VALUE(*value_ptr_ptr, value_ptr);
  522: 				value_ptr = *value_ptr_ptr;
  523: 				zendi_zval_copy_ctor(*value_ptr);
  524: 			}
  525: 			Z_SET_REFCOUNT_P(value_ptr, 1);
  526: 			Z_SET_ISREF_P(value_ptr);
  527: 		}
  528: 
  529: 		*variable_ptr_ptr = value_ptr;
  530: 		Z_ADDREF_P(value_ptr);
  531: 
  532: 		zval_ptr_dtor(&variable_ptr);
  533: 	} else if (!Z_ISREF_P(variable_ptr)) {
  534: 		if (variable_ptr_ptr == value_ptr_ptr) {
  535: 			SEPARATE_ZVAL(variable_ptr_ptr);
  536: 		} else if (variable_ptr==&EG(uninitialized_zval)
  537: 			|| Z_REFCOUNT_P(variable_ptr)>2) {
  538: 			/* we need to separate */
  539: 			Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2);
  540: 			ALLOC_ZVAL(*variable_ptr_ptr);
  541: 			ZVAL_COPY_VALUE(*variable_ptr_ptr, variable_ptr);
  542: 			zval_copy_ctor(*variable_ptr_ptr);
  543: 			*value_ptr_ptr = *variable_ptr_ptr;
  544: 			Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2);
  545: 		}
  546: 		Z_SET_ISREF_PP(variable_ptr_ptr);
  547: 	}
  548: }
  549: 
  550: /* this should modify object only if it's empty */
  551: static inline void make_real_object(zval **object_ptr TSRMLS_DC)
  552: {
  553: 	if (Z_TYPE_PP(object_ptr) == IS_NULL
  554: 		|| (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0)
  555: 		|| (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0)
  556: 	) {
  557: 		zend_error(E_WARNING, "Creating default object from empty value");
  558: 
  559: 		SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
  560: 		zval_dtor(*object_ptr);
  561: 		object_init(*object_ptr);
  562: 	}
  563: }
  564: 
  565: ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)
  566: {
  567: 	*pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
  568: 
  569: 	*class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
  570: 	if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
  571: 		return "implement interface ";
  572: 	} else {
  573: 		return "be an instance of ";
  574: 	}
  575: }
  576: 
  577: ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC)
  578: {
  579: 	zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
  580: 	const char *fname = zf->common.function_name;
  581: 	char *fsep;
  582: 	const char *fclass;
  583: 
  584: 	if (zf->common.scope) {
  585: 		fsep =  "::";
  586: 		fclass = zf->common.scope->name;
  587: 	} else {
  588: 		fsep =  "";
  589: 		fclass = "";
  590: 	}
  591: 
  592: 	if (ptr && ptr->op_array) {
  593: 		zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, ptr->opline->lineno);
  594: 	} else {
  595: 		zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
  596: 	}
  597: 	return 0;
  598: }
  599: 
  600: static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC)
  601: {
  602: 	zend_arg_info *cur_arg_info;
  603: 	char *need_msg;
  604: 	zend_class_entry *ce;
  605: 
  606: 	if (!zf->common.arg_info
  607: 		|| arg_num>zf->common.num_args) {
  608: 		return 1;
  609: 	}
  610: 
  611: 	cur_arg_info = &zf->common.arg_info[arg_num-1];
  612: 
  613: 	if (cur_arg_info->class_name) {
  614: 		const char *class_name;
  615: 
  616: 		if (!arg) {
  617: 			need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
  618: 			return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "" TSRMLS_CC);
  619: 		}
  620: 		if (Z_TYPE_P(arg) == IS_OBJECT) {
  621: 			need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
  622: 			if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
  623: 				return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
  624: 			}
  625: 		} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
  626: 			need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
  627: 			return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
  628: 		}
  629: 	} else if (cur_arg_info->type_hint) {
  630: 		switch(cur_arg_info->type_hint) {
  631: 			case IS_ARRAY:
  632: 				if (!arg) {
  633: 					return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC);
  634: 				}
  635: 
  636: 				if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
  637: 					return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
  638: 				}
  639: 				break;
  640: 
  641: 			case IS_CALLABLE:
  642: 				if (!arg) {
  643: 					return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "" TSRMLS_CC);
  644: 				}
  645: 				if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
  646: 					return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "" TSRMLS_CC);
  647: 				}
  648: 				break;
  649: 
  650: 			default:
  651: 				zend_error(E_ERROR, "Unknown typehint");
  652: 		}
  653: 	}
  654: 	return 1;
  655: }
  656: 
  657: static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const temp_variable *Ts, int opcode, const zend_literal *key TSRMLS_DC)
  658: {
  659: 	zval *object = *object_ptr;
  660: 	zend_free_op free_value;
  661:  	zval *value = get_zval_ptr(value_type, value_op, Ts, &free_value, BP_VAR_R);
  662: 
  663: 	if (Z_TYPE_P(object) != IS_OBJECT) {
  664: 		if (object == &EG(error_zval)) {
  665:  			if (retval) {
  666: 				*retval = &EG(uninitialized_zval);
  667: 				PZVAL_LOCK(*retval);
  668: 			}
  669: 			FREE_OP(free_value);
  670: 			return;
  671: 		}
  672: 		if (Z_TYPE_P(object) == IS_NULL ||
  673: 		    (Z_TYPE_P(object) == IS_BOOL && Z_LVAL_P(object) == 0) ||
  674: 		    (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
  675: 			SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
  676: 			object = *object_ptr;
  677: 			Z_ADDREF_P(object);
  678: 			zend_error(E_WARNING, "Creating default object from empty value");
  679: 			if (Z_REFCOUNT_P(object) == 1) {
  680: 				/* object was removed by error handler, nothing to assign to */
  681: 				zval_ptr_dtor(&object);
  682: 				if (retval) {
  683: 					*retval = &EG(uninitialized_zval);
  684: 					PZVAL_LOCK(*retval);
  685: 				}
  686: 				FREE_OP(free_value);
  687: 				return;
  688: 			}
  689: 			Z_DELREF_P(object);
  690: 			zval_dtor(object);
  691: 			object_init(object);
  692: 		} else {
  693: 			zend_error(E_WARNING, "Attempt to assign property of non-object");
  694: 			if (retval) {
  695: 				*retval = &EG(uninitialized_zval);
  696: 				PZVAL_LOCK(*retval);
  697: 			}
  698: 			FREE_OP(free_value);
  699: 			return;
  700: 		}
  701: 	}
  702: 
  703: 	/* separate our value if necessary */
  704: 	if (value_type == IS_TMP_VAR) {
  705: 		zval *orig_value = value;
  706: 
  707: 		ALLOC_ZVAL(value);
  708: 		ZVAL_COPY_VALUE(value, orig_value);
  709: 		Z_UNSET_ISREF_P(value);
  710: 		Z_SET_REFCOUNT_P(value, 0);
  711: 	} else if (value_type == IS_CONST) {
  712: 		zval *orig_value = value;
  713: 
  714: 		ALLOC_ZVAL(value);
  715: 		ZVAL_COPY_VALUE(value, orig_value);
  716: 		Z_UNSET_ISREF_P(value);
  717: 		Z_SET_REFCOUNT_P(value, 0);
  718: 		zval_copy_ctor(value);
  719: 	}
  720: 
  721: 
  722: 	Z_ADDREF_P(value);
  723: 	if (opcode == ZEND_ASSIGN_OBJ) {
  724: 		if (!Z_OBJ_HT_P(object)->write_property) {
  725: 			zend_error(E_WARNING, "Attempt to assign property of non-object");
  726: 			if (retval) {
  727: 				*retval = &EG(uninitialized_zval);
  728: 				PZVAL_LOCK(&EG(uninitialized_zval));
  729: 			}
  730: 			if (value_type == IS_TMP_VAR) {
  731: 				FREE_ZVAL(value);
  732: 			} else if (value_type == IS_CONST) {
  733: 				zval_ptr_dtor(&value);
  734: 			}
  735: 			FREE_OP(free_value);
  736: 			return;
  737: 		}
  738: 		Z_OBJ_HT_P(object)->write_property(object, property_name, value, key TSRMLS_CC);
  739: 	} else {
  740: 		/* Note:  property_name in this case is really the array index! */
  741: 		if (!Z_OBJ_HT_P(object)->write_dimension) {
  742: 			zend_error_noreturn(E_ERROR, "Cannot use object as array");
  743: 		}
  744: 		Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
  745: 	}
  746: 
  747: 	if (retval && !EG(exception)) {
  748: 		*retval = value;
  749: 		PZVAL_LOCK(value);
  750: 	}
  751: 	zval_ptr_dtor(&value);
  752: 	FREE_OP_IF_VAR(free_value);
  753: }
  754: 
  755: static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC)
  756: {
  757: 	if (Z_TYPE_P(T->str_offset.str) == IS_STRING) {
  758: 
  759: 		if (((int)T->str_offset.offset < 0)) {
  760: 			zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
  761: 			return 0;
  762: 		}
  763: 
  764: 		if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
  765: 			if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
  766: 				char *tmp = (char *) emalloc(T->str_offset.offset+1+1);
  767: 
  768: 				memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str)+1);
  769: 				Z_STRVAL_P(T->str_offset.str) = tmp;
  770: 			} else {
  771: 				Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
  772: 			}
  773: 			memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
  774: 			       ' ',
  775: 			       T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
  776: 			Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
  777: 			Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
  778: 		} else if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
  779: 			char *tmp = (char *) emalloc(Z_STRLEN_P(T->str_offset.str) + 1);
  780: 
  781: 			memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str) + 1);
  782: 			Z_STRVAL_P(T->str_offset.str) = tmp;
  783: 		}
  784: 
  785: 		if (Z_TYPE_P(value) != IS_STRING) {
  786: 			zval tmp;
  787: 
  788: 			ZVAL_COPY_VALUE(&tmp, value);
  789: 			if (value_type != IS_TMP_VAR) {
  790: 				zval_copy_ctor(&tmp);
  791: 			}
  792: 			convert_to_string(&tmp);
  793: 			Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL(tmp)[0];
  794: 			STR_FREE(Z_STRVAL(tmp));
  795: 		} else {
  796: 			Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(value)[0];
  797: 			if (value_type == IS_TMP_VAR) {
  798: 				/* we can safely free final_value here
  799: 				 * because separation is done only
  800: 				 * in case value_type == IS_VAR */
  801: 				STR_FREE(Z_STRVAL_P(value));
  802: 			}
  803: 		}
  804: 		/*
  805: 		 * the value of an assignment to a string offset is undefined
  806: 		T(result->u.var).var = &T->str_offset.str;
  807: 		*/
  808: 	}
  809: 	return 1;
  810: }
  811: 
  812: 
  813: static inline zval* zend_assign_tmp_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
  814: {
  815: 	zval *variable_ptr = *variable_ptr_ptr;
  816: 	zval garbage;
  817: 
  818: 	if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
  819: 	    UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
  820: 		Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
  821: 		return variable_ptr;
  822: 	}
  823: 
  824:  	if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) &&
  825:  	    EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
  826:  	    /* we need to split */
  827: 		Z_DELREF_P(variable_ptr);
  828: 		GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
  829: 		ALLOC_ZVAL(variable_ptr);
  830: 		INIT_PZVAL_COPY(variable_ptr, value);
  831: 		*variable_ptr_ptr = variable_ptr;
  832: 		return variable_ptr;
  833: 	} else {
  834: 		if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
  835: 			/* nothing to destroy */
  836: 			ZVAL_COPY_VALUE(variable_ptr, value);
  837: 		} else {
  838: 			ZVAL_COPY_VALUE(&garbage, variable_ptr);
  839: 			ZVAL_COPY_VALUE(variable_ptr, value);
  840: 			_zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
  841: 		}
  842: 		return variable_ptr;
  843: 	}
  844: }
  845: 
  846: static inline zval* zend_assign_const_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
  847: {
  848: 	zval *variable_ptr = *variable_ptr_ptr;
  849: 	zval garbage;
  850: 
  851: 	if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
  852: 	    UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
  853: 		Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
  854: 		return variable_ptr;
  855: 	}
  856: 
  857:  	if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) &&
  858:  	    EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
  859: 		/* we need to split */
  860: 		Z_DELREF_P(variable_ptr);
  861: 		GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
  862: 		ALLOC_ZVAL(variable_ptr);
  863: 		INIT_PZVAL_COPY(variable_ptr, value);
  864: 		zval_copy_ctor(variable_ptr);
  865: 		*variable_ptr_ptr = variable_ptr;
  866: 		return variable_ptr;
  867:  	} else {
  868: 		if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
  869: 			/* nothing to destroy */
  870: 			ZVAL_COPY_VALUE(variable_ptr, value);
  871: 			zendi_zval_copy_ctor(*variable_ptr);
  872: 		} else {
  873: 			ZVAL_COPY_VALUE(&garbage, variable_ptr);
  874: 			ZVAL_COPY_VALUE(variable_ptr, value);
  875: 			zendi_zval_copy_ctor(*variable_ptr);
  876: 			_zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
  877: 		}
  878: 		return variable_ptr;
  879: 	}
  880: }
  881: 
  882: static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
  883: {
  884: 	zval *variable_ptr = *variable_ptr_ptr;
  885: 	zval garbage;
  886: 
  887: 	if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
  888: 	    UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
  889: 		Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
  890: 		return variable_ptr;
  891: 	}
  892: 
  893:  	if (EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
  894: 		if (Z_REFCOUNT_P(variable_ptr)==1) {
  895: 			if (UNEXPECTED(variable_ptr == value)) {
  896: 				return variable_ptr;
  897: 			} else if (EXPECTED(!PZVAL_IS_REF(value))) {
  898: 				Z_ADDREF_P(value);
  899: 				*variable_ptr_ptr = value;
  900: 				if (EXPECTED(variable_ptr != &EG(uninitialized_zval))) {
  901: 					GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
  902: 					zval_dtor(variable_ptr);
  903: 					efree(variable_ptr);
  904: 				} else {
  905: 					Z_DELREF_P(variable_ptr);
  906: 				}
  907: 				return value;
  908: 			} else {
  909: 				goto copy_value;
  910: 			}
  911: 		} else { /* we need to split */
  912: 			Z_DELREF_P(variable_ptr);
  913: 			GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
  914: 			if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
  915: 				ALLOC_ZVAL(variable_ptr);
  916: 				*variable_ptr_ptr = variable_ptr;
  917: 				INIT_PZVAL_COPY(variable_ptr, value);
  918: 				zval_copy_ctor(variable_ptr);
  919: 				return variable_ptr;
  920: 			} else {
  921: 				*variable_ptr_ptr = value;
  922: 				Z_ADDREF_P(value);
  923: 				Z_UNSET_ISREF_P(value);
  924: 				return value;
  925: 			}
  926: 		}
  927:  	} else {
  928: 		if (EXPECTED(variable_ptr != value)) {
  929: copy_value:
  930: 			if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
  931: 				/* nothing to destroy */
  932: 				ZVAL_COPY_VALUE(variable_ptr, value);
  933: 				zendi_zval_copy_ctor(*variable_ptr);
  934: 			} else {
  935: 				ZVAL_COPY_VALUE(&garbage, variable_ptr);
  936: 				ZVAL_COPY_VALUE(variable_ptr, value);
  937: 				zendi_zval_copy_ctor(*variable_ptr);
  938: 				_zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
  939: 			}
  940: 		}
  941: 		return variable_ptr;
  942: 	}
  943: }
  944: 
  945: /* Utility Functions for Extensions */
  946: static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
  947: {
  948: 	if (extension->statement_handler) {
  949: 		extension->statement_handler(op_array);
  950: 	}
  951: }
  952: 
  953: 
  954: static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
  955: {
  956: 	if (extension->fcall_begin_handler) {
  957: 		extension->fcall_begin_handler(op_array);
  958: 	}
  959: }
  960: 
  961: 
  962: static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
  963: {
  964: 	if (extension->fcall_end_handler) {
  965: 		extension->fcall_end_handler(op_array);
  966: 	}
  967: }
  968: 
  969: 
  970: static inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC)
  971: {
  972: 	switch (fetch_type) {
  973: 		case ZEND_FETCH_LOCAL:
  974: 			if (!EG(active_symbol_table)) {
  975: 				zend_rebuild_symbol_table(TSRMLS_C);
  976: 			}
  977: 			return EG(active_symbol_table);
  978: 			break;
  979: 		case ZEND_FETCH_GLOBAL:
  980: 		case ZEND_FETCH_GLOBAL_LOCK:
  981: 			return &EG(symbol_table);
  982: 			break;
  983: 		case ZEND_FETCH_STATIC:
  984: 			if (!EG(active_op_array)->static_variables) {
  985: 				ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
  986: 				zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
  987: 			}
  988: 			return EG(active_op_array)->static_variables;
  989: 			break;
  990: 		EMPTY_SWITCH_DEFAULT_CASE()
  991: 	}
  992: 	return NULL;
  993: }
  994: 
  995: static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
  996: {
  997: 	zval **retval;
  998: 	char *offset_key;
  999: 	int offset_key_length;
 1000: 	ulong hval;
 1001: 
 1002: 	switch (dim->type) {
 1003: 		case IS_NULL:
 1004: 			offset_key = "";
 1005: 			offset_key_length = 0;
 1006: 			hval = zend_inline_hash_func("", 1);
 1007: 			goto fetch_string_dim;
 1008: 
 1009: 		case IS_STRING:
 1010: 
 1011: 			offset_key = dim->value.str.val;
 1012: 			offset_key_length = dim->value.str.len;
 1013: 
 1014: 			if (dim_type == IS_CONST) {
 1015: 				hval = Z_HASH_P(dim);
 1016: 			} else {
 1017: 				ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, hval, goto num_index);
 1018: 				if (IS_INTERNED(offset_key)) {
 1019: 					hval = INTERNED_HASH(offset_key);
 1020: 				} else {
 1021: 					hval = zend_hash_func(offset_key, offset_key_length+1);
 1022: 				}
 1023: 			}
 1024: fetch_string_dim:
 1025: 			if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) {
 1026: 				switch (type) {
 1027: 					case BP_VAR_R:
 1028: 						zend_error(E_NOTICE, "Undefined index: %s", offset_key);
 1029: 						/* break missing intentionally */
 1030: 					case BP_VAR_UNSET:
 1031: 					case BP_VAR_IS:
 1032: 						retval = &EG(uninitialized_zval_ptr);
 1033: 						break;
 1034: 					case BP_VAR_RW:
 1035: 						zend_error(E_NOTICE,"Undefined index: %s", offset_key);
 1036: 						/* break missing intentionally */
 1037: 					case BP_VAR_W: {
 1038: 							zval *new_zval = &EG(uninitialized_zval);
 1039: 
 1040: 							Z_ADDREF_P(new_zval);
 1041: 							zend_hash_quick_update(ht, offset_key, offset_key_length+1, hval, &new_zval, sizeof(zval *), (void **) &retval);
 1042: 						}
 1043: 						break;
 1044: 				}
 1045: 			}
 1046: 			break;
 1047: 		case IS_DOUBLE:
 1048: 			hval = zend_dval_to_lval(Z_DVAL_P(dim));
 1049: 			goto num_index;
 1050: 		case IS_RESOURCE:
 1051: 			zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
 1052: 			/* Fall Through */
 1053: 		case IS_BOOL:
 1054: 		case IS_LONG:
 1055: 			hval = Z_LVAL_P(dim);
 1056: num_index:
 1057: 			if (zend_hash_index_find(ht, hval, (void **) &retval) == FAILURE) {
 1058: 				switch (type) {
 1059: 					case BP_VAR_R:
 1060: 						zend_error(E_NOTICE,"Undefined offset: %ld", hval);
 1061: 						/* break missing intentionally */
 1062: 					case BP_VAR_UNSET:
 1063: 					case BP_VAR_IS:
 1064: 						retval = &EG(uninitialized_zval_ptr);
 1065: 						break;
 1066: 					case BP_VAR_RW:
 1067: 						zend_error(E_NOTICE,"Undefined offset: %ld", hval);
 1068: 						/* break missing intentionally */
 1069: 					case BP_VAR_W: {
 1070: 						zval *new_zval = &EG(uninitialized_zval);
 1071: 
 1072: 						Z_ADDREF_P(new_zval);
 1073: 						zend_hash_index_update(ht, hval, &new_zval, sizeof(zval *), (void **) &retval);
 1074: 					}
 1075: 					break;
 1076: 				}
 1077: 			}
 1078: 			break;
 1079: 
 1080: 		default:
 1081: 			zend_error(E_WARNING, "Illegal offset type");
 1082: 			return (type == BP_VAR_W || type == BP_VAR_RW) ?
 1083: 				&EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
 1084: 	}
 1085: 	return retval;
 1086: }
 1087: 
 1088: static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC)
 1089: {
 1090: 	zval *container = *container_ptr;
 1091: 	zval **retval;
 1092: 
 1093: 	switch (Z_TYPE_P(container)) {
 1094: 
 1095: 		case IS_ARRAY:
 1096: 			if (type != BP_VAR_UNSET && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) {
 1097: 				SEPARATE_ZVAL(container_ptr);
 1098: 				container = *container_ptr;
 1099: 			}
 1100: fetch_from_array:
 1101: 			if (dim == NULL) {
 1102: 				zval *new_zval = &EG(uninitialized_zval);
 1103: 
 1104: 				Z_ADDREF_P(new_zval);
 1105: 				if (zend_hash_next_index_insert(Z_ARRVAL_P(container), &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) {
 1106: 					zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
 1107: 					retval = &EG(error_zval_ptr);
 1108: 					Z_DELREF_P(new_zval);
 1109: 				}
 1110: 			} else {
 1111: 				retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
 1112: 			}
 1113: 			result->var.ptr_ptr = retval;
 1114: 			PZVAL_LOCK(*retval);
 1115: 			return;
 1116: 			break;
 1117: 
 1118: 		case IS_NULL:
 1119: 			if (container == &EG(error_zval)) {
 1120: 				result->var.ptr_ptr = &EG(error_zval_ptr);
 1121: 				PZVAL_LOCK(EG(error_zval_ptr));
 1122: 			} else if (type != BP_VAR_UNSET) {
 1123: convert_to_array:
 1124: 				if (!PZVAL_IS_REF(container)) {
 1125: 					SEPARATE_ZVAL(container_ptr);
 1126: 					container = *container_ptr;
 1127: 				}
 1128: 				zval_dtor(container);
 1129: 				array_init(container);
 1130: 				goto fetch_from_array;
 1131: 			} else {
 1132: 				/* for read-mode only */
 1133: 				result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
 1134: 				PZVAL_LOCK(EG(uninitialized_zval_ptr));
 1135: 			}
 1136: 			return;
 1137: 			break;
 1138: 
 1139: 		case IS_STRING: {
 1140: 				zval tmp;
 1141: 
 1142: 				if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
 1143: 					goto convert_to_array;
 1144: 				}
 1145: 				if (dim == NULL) {
 1146: 					zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
 1147: 				}
 1148: 
 1149: 				if (Z_TYPE_P(dim) != IS_LONG) {
 1150: 
 1151: 					switch(Z_TYPE_P(dim)) {
 1152: 						/* case IS_LONG: */
 1153: 						case IS_STRING:
 1154: 							if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
 1155: 								break;
 1156: 							}
 1157: 							if (type != BP_VAR_UNSET) {
 1158: 								zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val);
 1159: 							}
 1160: 
 1161: 							break;
 1162: 						case IS_DOUBLE:
 1163: 						case IS_NULL:
 1164: 						case IS_BOOL:
 1165: 							zend_error(E_NOTICE, "String offset cast occured");
 1166: 							break;
 1167: 						default:
 1168: 							zend_error(E_WARNING, "Illegal offset type");
 1169: 							break;
 1170: 					}
 1171: 
 1172: 					tmp = *dim;
 1173: 					zval_copy_ctor(&tmp);
 1174: 					convert_to_long(&tmp);
 1175: 					dim = &tmp;
 1176: 				}
 1177: 				if (type != BP_VAR_UNSET) {
 1178: 					SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
 1179: 				}
 1180: 				container = *container_ptr;
 1181: 				result->str_offset.str = container;
 1182: 				PZVAL_LOCK(container);
 1183: 				result->str_offset.offset = Z_LVAL_P(dim);
 1184: 				result->str_offset.ptr_ptr = NULL;
 1185: 				return;
 1186: 			}
 1187: 			break;
 1188: 
 1189: 		case IS_OBJECT:
 1190: 			if (!Z_OBJ_HT_P(container)->read_dimension) {
 1191: 				zend_error_noreturn(E_ERROR, "Cannot use object as array");
 1192: 			} else {
 1193: 				zval *overloaded_result;
 1194: 
 1195: 				if (dim_type == IS_TMP_VAR) {
 1196: 					zval *orig = dim;
 1197: 					MAKE_REAL_ZVAL_PTR(dim);
 1198: 					ZVAL_NULL(orig);
 1199: 				}
 1200: 				overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
 1201: 
 1202: 				if (overloaded_result) {
 1203: 					if (!Z_ISREF_P(overloaded_result)) {
 1204: 						if (Z_REFCOUNT_P(overloaded_result) > 0) {
 1205: 							zval *tmp = overloaded_result;
 1206: 
 1207: 							ALLOC_ZVAL(overloaded_result);
 1208: 							ZVAL_COPY_VALUE(overloaded_result, tmp);
 1209: 							zval_copy_ctor(overloaded_result);
 1210: 							Z_UNSET_ISREF_P(overloaded_result);
 1211: 							Z_SET_REFCOUNT_P(overloaded_result, 0);
 1212: 						}
 1213: 						if (Z_TYPE_P(overloaded_result) != IS_OBJECT) {
 1214: 							zend_class_entry *ce = Z_OBJCE_P(container);
 1215: 							zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name);
 1216: 						}
 1217: 					}
 1218: 					retval = &overloaded_result;
 1219: 				} else {
 1220: 					retval = &EG(error_zval_ptr);
 1221: 				}
 1222: 				AI_SET_PTR(result, *retval);
 1223: 				PZVAL_LOCK(*retval);
 1224: 				if (dim_type == IS_TMP_VAR) {
 1225: 					zval_ptr_dtor(&dim);
 1226: 				}
 1227: 			}
 1228: 			return;
 1229: 			break;
 1230: 
 1231: 		case IS_BOOL:
 1232: 			if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
 1233: 				goto convert_to_array;
 1234: 			}
 1235: 			/* break missing intentionally */
 1236: 
 1237: 		default:
 1238: 			if (type == BP_VAR_UNSET) {
 1239: 				zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
 1240: 				AI_SET_PTR(result, &EG(uninitialized_zval));
 1241: 				PZVAL_LOCK(&EG(uninitialized_zval));
 1242: 			} else {
 1243: 				zend_error(E_WARNING, "Cannot use a scalar value as an array");
 1244: 				result->var.ptr_ptr = &EG(error_zval_ptr);
 1245: 				PZVAL_LOCK(EG(error_zval_ptr));
 1246: 			}
 1247: 			break;
 1248: 	}
 1249: }
 1250: 
 1251: static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC)
 1252: {
 1253: 	zval *container = *container_ptr;
 1254: 	zval **retval;
 1255: 
 1256: 	switch (Z_TYPE_P(container)) {
 1257: 
 1258: 		case IS_ARRAY:
 1259: 			retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
 1260: 			AI_SET_PTR(result, *retval);
 1261: 			PZVAL_LOCK(*retval);
 1262: 			return;
 1263: 
 1264: 		case IS_NULL:
 1265: 			AI_SET_PTR(result, &EG(uninitialized_zval));
 1266: 			PZVAL_LOCK(&EG(uninitialized_zval));
 1267: 			return;
 1268: 
 1269: 		case IS_STRING: {
 1270: 				zval tmp;
 1271: 				zval *ptr;
 1272: 
 1273: 				if (Z_TYPE_P(dim) != IS_LONG) {
 1274: 					switch(Z_TYPE_P(dim)) {
 1275: 						/* case IS_LONG: */
 1276: 						case IS_STRING:
 1277: 							if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
 1278: 								break;
 1279: 							}
 1280: 							if (type != BP_VAR_IS) {
 1281: 								zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val);
 1282: 							}
 1283: 							break;
 1284: 						case IS_DOUBLE:
 1285: 						case IS_NULL:
 1286: 						case IS_BOOL:
 1287: 							if (type != BP_VAR_IS) {
 1288: 								zend_error(E_NOTICE, "String offset cast occured");
 1289: 							}
 1290: 							break;
 1291: 						default:
 1292: 							zend_error(E_WARNING, "Illegal offset type");
 1293: 							break;
 1294: 					}
 1295: 
 1296: 					ZVAL_COPY_VALUE(&tmp, dim);
 1297: 					zval_copy_ctor(&tmp);
 1298: 					convert_to_long(&tmp);
 1299: 					dim = &tmp;
 1300: 				}
 1301: 
 1302: 				ALLOC_ZVAL(ptr);
 1303: 				INIT_PZVAL(ptr);
 1304: 				Z_TYPE_P(ptr) = IS_STRING;
 1305: 
 1306: 				if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) {
 1307: 					if (type != BP_VAR_IS) {
 1308: 						zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
 1309: 					}
 1310: 					Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC();
 1311: 					Z_STRLEN_P(ptr) = 0;
 1312: 				} else {
 1313: 					Z_STRVAL_P(ptr) = (char*)emalloc(2);
 1314: 					Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_LVAL_P(dim)];
 1315: 					Z_STRVAL_P(ptr)[1] = 0;
 1316: 					Z_STRLEN_P(ptr) = 1;
 1317: 				}
 1318: 				AI_SET_PTR(result, ptr);
 1319: 				return;
 1320: 			}
 1321: 			break;
 1322: 
 1323: 		case IS_OBJECT:
 1324: 			if (!Z_OBJ_HT_P(container)->read_dimension) {
 1325: 				zend_error_noreturn(E_ERROR, "Cannot use object as array");
 1326: 			} else {
 1327: 				zval *overloaded_result;
 1328: 
 1329: 				if (dim_type == IS_TMP_VAR) {
 1330: 					zval *orig = dim;
 1331: 					MAKE_REAL_ZVAL_PTR(dim);
 1332: 					ZVAL_NULL(orig);
 1333: 				}
 1334: 				overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
 1335: 
 1336: 				if (overloaded_result) {
 1337: 					AI_SET_PTR(result, overloaded_result);
 1338: 					PZVAL_LOCK(overloaded_result);
 1339: 				} else if (result) {
 1340: 					AI_SET_PTR(result, &EG(uninitialized_zval));
 1341: 					PZVAL_LOCK(&EG(uninitialized_zval));
 1342: 				}
 1343: 				if (dim_type == IS_TMP_VAR) {
 1344: 					zval_ptr_dtor(&dim);
 1345: 				}
 1346: 			}
 1347: 			return;
 1348: 
 1349: 		default:
 1350: 			AI_SET_PTR(result, &EG(uninitialized_zval));
 1351: 			PZVAL_LOCK(&EG(uninitialized_zval));
 1352: 			return;
 1353: 	}
 1354: }
 1355: 
 1356: static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC)
 1357: {
 1358: 	zval *container = *container_ptr;;
 1359: 
 1360: 	if (Z_TYPE_P(container) != IS_OBJECT) {
 1361: 		if (container == &EG(error_zval)) {
 1362: 			result->var.ptr_ptr = &EG(error_zval_ptr);
 1363: 			PZVAL_LOCK(EG(error_zval_ptr));
 1364: 			return;
 1365: 		}
 1366: 
 1367: 		/* this should modify object only if it's empty */
 1368: 		if (type != BP_VAR_UNSET &&
 1369: 		    ((Z_TYPE_P(container) == IS_NULL ||
 1370: 		     (Z_TYPE_P(container) == IS_BOOL && Z_LVAL_P(container)==0) ||
 1371: 		     (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
 1372: 			if (!PZVAL_IS_REF(container)) {
 1373: 				SEPARATE_ZVAL(container_ptr);
 1374: 				container = *container_ptr;
 1375: 			}
 1376: 			object_init(container);
 1377: 		} else {
 1378: 			zend_error(E_WARNING, "Attempt to modify property of non-object");
 1379: 			result->var.ptr_ptr = &EG(error_zval_ptr);
 1380: 			PZVAL_LOCK(EG(error_zval_ptr));
 1381: 			return;
 1382: 		}
 1383: 	}
 1384: 
 1385: 	if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
 1386: 		zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, key TSRMLS_CC);
 1387: 		if (NULL == ptr_ptr) {
 1388: 			zval *ptr;
 1389: 
 1390: 			if (Z_OBJ_HT_P(container)->read_property &&
 1391: 				(ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC)) != NULL) {
 1392: 				AI_SET_PTR(result, ptr);
 1393: 				PZVAL_LOCK(ptr);
 1394: 			} else {
 1395: 				zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
 1396: 			}
 1397: 		} else {
 1398: 			result->var.ptr_ptr = ptr_ptr;
 1399: 			PZVAL_LOCK(*ptr_ptr);
 1400: 		}
 1401: 	} else if (Z_OBJ_HT_P(container)->read_property) {
 1402: 		zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC);
 1403: 
 1404: 		AI_SET_PTR(result, ptr);
 1405: 		PZVAL_LOCK(ptr);
 1406: 	} else {
 1407: 		zend_error(E_WARNING, "This object doesn't support property references");
 1408: 		result->var.ptr_ptr = &EG(error_zval_ptr);
 1409: 		PZVAL_LOCK(EG(error_zval_ptr));
 1410: 	}
 1411: }
 1412: 
 1413: static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)
 1414: {
 1415: 	int original_nest_levels = nest_levels;
 1416: 	zend_brk_cont_element *jmp_to;
 1417: 
 1418: 	do {
 1419: 		if (array_offset==-1) {
 1420: 			zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
 1421: 		}
 1422: 		jmp_to = &op_array->brk_cont_array[array_offset];
 1423: 		if (nest_levels>1) {
 1424: 			zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
 1425: 
 1426: 			switch (brk_opline->opcode) {
 1427: 				case ZEND_SWITCH_FREE:
 1428: 					if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
 1429: 						zval_ptr_dtor(&T(brk_opline->op1.var).var.ptr);
 1430: 					}
 1431: 					break;
 1432: 				case ZEND_FREE:
 1433: 					if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
 1434: 						zendi_zval_dtor(T(brk_opline->op1.var).tmp_var);
 1435: 					}
 1436: 					break;
 1437: 			}
 1438: 		}
 1439: 		array_offset = jmp_to->parent;
 1440: 	} while (--nest_levels > 0);
 1441: 	return jmp_to;
 1442: }
 1443: 
 1444: #if ZEND_INTENSIVE_DEBUGGING
 1445: 
 1446: #define CHECK_SYMBOL_TABLES()														\
 1447: 	zend_hash_apply(&EG(symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);	\
 1448: 	if (&EG(symbol_table)!=EG(active_symbol_table)) {								\
 1449: 		zend_hash_apply(EG(active_symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);	\
 1450: 	}
 1451: 
 1452: static int zend_check_symbol(zval **pz TSRMLS_DC)
 1453: {
 1454: 	if (Z_TYPE_PP(pz) > 9) {
 1455: 		fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
 1456: /* See http://support.microsoft.com/kb/190351 */
 1457: #ifdef PHP_WIN32
 1458: 		fflush(stderr);
 1459: #endif
 1460: 	} else if (Z_TYPE_PP(pz) == IS_ARRAY) {
 1461: 		zend_hash_apply(Z_ARRVAL_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
 1462: 	} else if (Z_TYPE_PP(pz) == IS_OBJECT) {
 1463: 
 1464: 		/* OBJ-TBI - doesn't support new object model! */
 1465: 		zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
 1466: 	}
 1467: 
 1468: 	return 0;
 1469: }
 1470: 
 1471: 
 1472: #else
 1473: #define CHECK_SYMBOL_TABLES()
 1474: #endif
 1475: 
 1476: ZEND_API opcode_handler_t *zend_opcode_handlers;
 1477: 
 1478: ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
 1479: {
 1480: 	zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr;
 1481: 	((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);
 1482: }
 1483: 
 1484: #define ZEND_VM_NEXT_OPCODE() \
 1485: 	CHECK_SYMBOL_TABLES() \
 1486: 	ZEND_VM_INC_OPCODE(); \
 1487: 	ZEND_VM_CONTINUE()
 1488: 
 1489: #define ZEND_VM_SET_OPCODE(new_op) \
 1490: 	CHECK_SYMBOL_TABLES() \
 1491: 	OPLINE = new_op
 1492: 
 1493: #define ZEND_VM_JMP(new_op) \
 1494: 	if (EXPECTED(!EG(exception))) { \
 1495: 		ZEND_VM_SET_OPCODE(new_op); \
 1496: 	} else { \
 1497: 		LOAD_OPLINE(); \
 1498: 	} \
 1499: 	ZEND_VM_CONTINUE()
 1500: 
 1501: #define ZEND_VM_INC_OPCODE() \
 1502: 	OPLINE++
 1503: 
 1504: #ifdef __GNUC__
 1505: # define ZEND_VM_GUARD(name) __asm__("#" #name)
 1506: #else
 1507: # define ZEND_VM_GUARD(name)
 1508: #endif
 1509: 
 1510: #include "zend_vm_execute.h"
 1511: 
 1512: ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
 1513: {
 1514: 	if (opcode != ZEND_USER_OPCODE) {
 1515: 		if (handler == NULL) {
 1516: 			/* restore the original handler */			
 1517: 			zend_user_opcodes[opcode] = opcode;
 1518: 		} else {
 1519: 			zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
 1520: 		}
 1521: 		zend_user_opcode_handlers[opcode] = handler;
 1522: 		return SUCCESS;
 1523: 	}
 1524: 	return FAILURE;
 1525: }
 1526: 
 1527: ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
 1528: {
 1529: 	return zend_user_opcode_handlers[opcode];
 1530: }
 1531: 
 1532: ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
 1533: 	return get_zval_ptr(op_type, node, Ts, should_free, type);
 1534: }
 1535: 
 1536: ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
 1537: 	return get_zval_ptr_ptr(op_type, node, Ts, should_free, type);
 1538: }
 1539: 
 1540: /*
 1541:  * Local variables:
 1542:  * tab-width: 4
 1543:  * c-basic-offset: 4
 1544:  * indent-tabs-mode: t
 1545:  * End:
 1546:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>