Example #1
0
int uopz_class_constant_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	if (EX(opline)->op1_type == IS_CONST) {
		zval *name = EX_CONSTANT(EX(opline)->op1);
		zend_string *key = Z_STR_P(name);
		zval *mock = NULL;
		zend_class_entry *poser = NULL;

		key = zend_string_tolower(key);
		
		if ((mock = zend_hash_find(&UOPZ(mocks), key))) {
			if (Z_TYPE_P(mock) == IS_OBJECT) {
				poser = Z_OBJCE_P(mock);
			} else poser = zend_lookup_class(Z_STR_P(mock));

			if (poser) {
				CACHE_PTR(Z_CACHE_SLOT_P(name), poser);
			}
		}

		zend_string_release(key);
	}

	CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)), NULL);

	if (uopz_fetch_class_constant_handler) {
		return uopz_fetch_class_constant_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
	
	return ZEND_USER_OPCODE_DISPATCH;
} /* }}} */
Example #2
0
int uopz_constant_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
#if PHP_VERSION_ID >= 70100
	if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)))) {
		CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)), NULL);
	}
#else
	if (EX(opline)->op1_type == IS_UNUSED) {
		if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)))) {
			CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)), NULL);
		}
	} else {
		zend_string *key = NULL;
		zval *mock = NULL;
		zend_class_entry *poser = NULL;

		if (EX(opline)->op1_type == IS_CONST) {
			key = zend_string_tolower(Z_STR_P(EX_CONSTANT(EX(opline)->op1)));			

			if ((mock = zend_hash_find(&UOPZ(mocks), key))) {
				if (Z_TYPE_P(mock) == IS_OBJECT) {
					poser = Z_OBJCE_P(mock);
				} else poser = zend_lookup_class(Z_STR_P(mock));
				CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op1)), poser);
			}

			if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)))) {
				CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)), NULL);
			}

			zend_string_release(key);		
		} else {
			key = zend_string_tolower(Z_CE_P(EX_VAR(EX(opline)->op1.var))->name);
			
			if ((mock = zend_hash_find(&UOPZ(mocks), key))) {
				if (Z_TYPE_P(mock) == IS_OBJECT) {
					poser = Z_OBJCE_P(mock);
				} else poser = zend_lookup_class(Z_STR_P(mock));

				Z_CE_P(EX_VAR(EX(opline)->op1.var)) = poser;
			}

			CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op2)), 
								  Z_CE_P(EX_VAR(EX(opline)->op1.var)), NULL);

			zend_string_release(key);
		}
	}
#endif

	if (uopz_fetch_constant_handler) {
		return uopz_fetch_constant_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	return ZEND_USER_OPCODE_DISPATCH;
} /* }}} */
static zval *get_zval_ptr_safe(
	int op_type, const znode_op *node, const zend_execute_data *execute_data
) {
#ifdef ZEND_ENGINE_3
	switch (op_type) {
		case IS_CONST:
			return EX_CONSTANT(*node);
		case IS_CV:
		case IS_TMP_VAR:
		case IS_VAR:
		{
			zval *zv = EX_VAR(node->var);
			ZVAL_DEREF(zv);
			return !Z_ISUNDEF_P(zv) ? zv : NULL;
		}
		default:
			return NULL;
	}
#else
	switch (op_type) {
		case IS_CONST:
			return node->zv;
		case IS_TMP_VAR:
			return &SO_EX_T(node->var).tmp_var;
		case IS_VAR:
			return SO_EX_T(node->var).var.ptr;
		case IS_CV: {
			zval **tmp = SO_EX_CV(node->constant);
			return tmp ? *tmp : NULL;
		}
		default:
			return NULL;
	}
#endif
}
Example #4
0
int uopz_add_class_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	zval *name = EX_CONSTANT(EX(opline)->op2);
	zend_string *key = zend_string_tolower(Z_STR_P(name));
	zval *mock = NULL;
	
	if ((mock = zend_hash_find(&UOPZ(mocks), key))) {
		if (Z_TYPE_P(mock) == IS_STRING) {
			zend_class_entry *ce = zend_lookup_class(Z_STR_P(mock));
			
			if (ce) {
				CACHE_PTR(Z_CACHE_SLOT_P(name), ce);
			}
		} else {
			CACHE_PTR(Z_CACHE_SLOT_P(name), Z_OBJCE_P(mock));
		}
	}
	
	zend_string_release(key);	

	if (uopz_add_trait_handler || uopz_add_interface_handler) {
		switch (EX(opline)->opcode) {
			case ZEND_ADD_INTERFACE:
				return uopz_add_interface_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);

			case ZEND_ADD_TRAIT:
				return uopz_add_trait_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		}
	}
	
	return ZEND_USER_OPCODE_DISPATCH;
} /* }}} */
Example #5
0
/* {{{ */
static int php_memoize_return(zend_execute_data *execute_data) {
	zend_long ttl = 0;
	const zend_function *fbc = EX(func);

	if (MG(ini.enabled) && php_memoize_is_memoizing(fbc, &ttl)) {
		zend_string *key = php_memoize_key(
			&EX(This),
			fbc, EX_NUM_ARGS(), EX_VAR_NUM(0));

		if (key) {
			zval *return_value;

			if (EX(opline)->op1_type & IS_CONST) {
				return_value = EX_CONSTANT(EX(opline)->op1);
			} else {
				return_value = EX_VAR(EX(opline)->op1.var);
			}

			apc_cache_store(php_memoize_cache, key, return_value, ttl, 1);

			if (EG(exception)) {
				zend_clear_exception();
			}

			zend_string_release(key);
		}
	}
	
	if (zend_return_function) {
		return zend_return_function(execute_data);
	}

	return ZEND_USER_OPCODE_DISPATCH;
} /* }}} */
static int coro_exit_handler(zend_execute_data *execute_data)
{
    zval ex;
    zend_object *obj;
    zend_long flags = 0;
    if (sw_get_current_cid() != -1)
    {
        flags |= SW_EXIT_IN_COROUTINE;
    }
    if (SwooleG.serv && SwooleG.serv->gs->start)
    {
        flags |= SW_EXIT_IN_SERVER;
    }
    if (flags)
    {
        const zend_op *opline = EX(opline);
        zval _exit_status;
        zval *exit_status = NULL;

        if (opline->op1_type != IS_UNUSED)
        {
            if (opline->op1_type == IS_CONST)
            {
                // see: https://github.com/php/php-src/commit/e70618aff6f447a298605d07648f2ce9e5a284f5
#ifdef EX_CONSTANT
                exit_status = EX_CONSTANT(opline->op1);
#else
                exit_status = RT_CONSTANT(opline, opline->op1);
#endif
            }
            else
            {
                exit_status = EX_VAR(opline->op1.var);
            }
            if (Z_ISREF_P(exit_status))
            {
                exit_status = Z_REFVAL_P(exit_status);
            }
        }
        else
        {
            exit_status = &_exit_status;
            ZVAL_NULL(exit_status);
        }
        obj = zend_throw_error_exception(swoole_exit_exception_class_entry_ptr, "swoole exit.", 0, E_ERROR TSRMLS_CC);
        ZVAL_OBJ(&ex, obj);
        zend_update_property_long(swoole_exit_exception_class_entry_ptr, &ex, ZEND_STRL("flags"), flags);
        Z_TRY_ADDREF_P(exit_status);
        zend_update_property(swoole_exit_exception_class_entry_ptr, &ex, ZEND_STRL("status"), exit_status);
    }

    return ZEND_USER_OPCODE_DISPATCH;
}
Example #7
0
static zval *smd_get_zval_ptr(zend_execute_data *execute_data, int op_type, znode_op op, zend_free_op *should_free, int type, int force_ret) /* {{{ */ {
    if (op_type & (IS_TMP_VAR|IS_VAR)) {
        return smd_get_zval_ptr_tmpvar(execute_data, op.var, should_free);
    } else {
        if (op_type == IS_CONST) {
            return EX_CONSTANT(op);
        } else if (op_type == IS_CV) {
            return smd_get_zval_ptr_cv(execute_data, op.var, type, force_ret);
        } else {
            return NULL;
        }
    }
} /* }}} */ 
Example #8
0
int uopz_no_exit_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	if (UOPZ(exit)) {
		if (uopz_exit_handler)
			return uopz_exit_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);

		return ZEND_USER_OPCODE_DISPATCH;
	}

	if (EX(opline)->op1_type != IS_UNUSED) {
		zval *estatus;

		if (EX(opline)->op1_type == IS_CONST) {
			estatus = EX_CONSTANT(EX(opline)->op1);
		} else estatus = EX_VAR(EX(opline)->op1.var);

		if (Z_ISREF_P(estatus)) {
			estatus = Z_REFVAL_P(estatus);
		}

		if (Z_TYPE_P(estatus) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(estatus);
		} else EG(exit_status) = 0;

		ZVAL_COPY(&UOPZ(estatus), estatus);
	}

	if (EX(opline) < &EX(func)->op_array.opcodes[EX(func)->op_array.last - 1]) {
		EX(opline)++;

		while (EX(opline)->opcode == ZEND_EXT_STMT) {
			EX(opline)++;
		}

		return ZEND_USER_OPCODE_CONTINUE;
	} else {
		return ZEND_USER_OPCODE_RETURN;
	}
} /* }}} */
Example #9
0
int uopz_fetch_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	zval *name = NULL;
	zend_string *key = NULL;
	int UOPZ_VM_ACTION = ZEND_USER_OPCODE_DISPATCH;

	do {
		if (EX(opline)->op2_type == IS_UNUSED) {
			break;
		}
		
		if (EX(opline)->op2_type == IS_CONST) {
			name = 
				EX_CONSTANT(EX(opline)->op2);
			if (name) {
				key = Z_STR_P(name);
			}			
		} else if (EX(opline)->op2_type != IS_UNUSED) {
			name = EX_VAR(EX(opline)->op2.var);
			if (Z_TYPE_P(name) == IS_STRING) {
				key = Z_STR_P(name);
			} else if (Z_TYPE_P(name) == IS_OBJECT) {
				key = Z_OBJCE_P(name)->name;
			} else {
				
			}
		}

		if (key) {
			zval *mock = NULL;
			zend_class_entry *ce = NULL;
			zend_string *lookup = zend_string_tolower(key);

			if (UNEXPECTED((mock = zend_hash_find(&UOPZ(mocks), lookup)))) {

				switch (Z_TYPE_P(mock)) {
					case IS_OBJECT: ce = Z_OBJCE_P(mock); break;
					case IS_STRING: ce = zend_lookup_class(Z_STR_P(mock)); break;
				}

				if (ce) {
					if (EX(opline)->op2_type == IS_CONST) {
						CACHE_PTR(Z_CACHE_SLOT_P(name), ce);
					}

					Z_CE_P(EX_VAR(EX(opline)->result.var)) = ce;
					UOPZ_VM_ACTION = ZEND_USER_OPCODE_CONTINUE;
				}
			}

			zend_string_release(lookup);
		}
	} while(0);

	if (UOPZ_VM_ACTION == ZEND_USER_OPCODE_CONTINUE) {
		EX(opline) = EX(opline) + 1;
	} else {
		if (uopz_fetch_class_handler) {
			return uopz_fetch_class_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		}
	}

	return UOPZ_VM_ACTION;
} /* }}} */
Example #10
0
int uopz_mock_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	int UOPZ_VM_ACTION = ZEND_USER_OPCODE_DISPATCH;
	zend_string *key;
	zval *mock = NULL;
	zend_class_entry *ce;

	if (EX(opline)->op1_type == IS_CONST) {
		ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op1)));

		if (UNEXPECTED(ce == NULL)) {
			key = Z_STR_P(EX_CONSTANT(EX(opline)->op1));
		} else {
			key = ce->name;
		}

		key = zend_string_tolower(key);
	} else if(EX(opline)->op1_type == IS_UNUSED) {
		ce = zend_fetch_class(NULL, EX(opline)->op1.num);
		if (UNEXPECTED(ce == NULL)) {
			return UOPZ_VM_ACTION;
		}
		key = 
			zend_string_tolower(ce->name);
	} else {
		key = zend_string_tolower(
			Z_CE_P(EX_VAR(EX(opline)->op1.var))->name);
	}

	if (UNEXPECTED((mock = zend_hash_find(&UOPZ(mocks), key)))) {
		switch (Z_TYPE_P(mock)) {
			case IS_OBJECT:
				ZVAL_COPY(
					EX_VAR(EX(opline)->result.var), mock);
#if PHP_VERSION_ID < 70100
				EX(opline) = 
					OP_JMP_ADDR(EX(opline), EX(opline)->op2);
#else
				if (EX(opline)->extended_value == 0 && 
					(EX(opline)+1)->opcode == ZEND_DO_FCALL) {
					EX(opline) += 2;
				}
#endif
				UOPZ_VM_ACTION = ZEND_USER_OPCODE_CONTINUE;
			break;

			case IS_STRING:
				ce = zend_lookup_class(Z_STR_P(mock));
				if (EXPECTED(ce)) {
					if (EX(opline)->op1_type == IS_CONST) {
						CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op1)), ce);
					} else if (EX(opline)->op1_type != IS_UNUSED) {
						Z_CE_P(EX_VAR(EX(opline)->op1.var)) = ce;
					} else {
						/* oh dear, can't do what is requested */			
					}
					
				}
			break;
		}
	}

	zend_string_release(key);

	if (UOPZ_VM_ACTION == ZEND_USER_OPCODE_DISPATCH) {
		if (uopz_new_handler) {
			return uopz_new_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		}
	}

	return UOPZ_VM_ACTION;
} /* }}} */
Example #11
0
int uopz_call_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	switch (EX(opline)->opcode) {
		case ZEND_INIT_FCALL_BY_NAME:
		case ZEND_INIT_FCALL:
		case ZEND_INIT_NS_FCALL_BY_NAME: {
			zval *function_name = EX_CONSTANT(EX(opline)->op2);
			CACHE_PTR(Z_CACHE_SLOT_P(function_name), NULL);
		} break;

		case ZEND_INIT_METHOD_CALL: {
			if (EX(opline)->op2_type == IS_CONST) {
				zval *function_name = EX_CONSTANT(EX(opline)->op2);
				CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), NULL, NULL);
			}
		} break;

		case ZEND_INIT_STATIC_METHOD_CALL: {
			zend_class_entry *ce;
			zval *mock;
			zend_string *key = NULL;
			
			if (EX(opline)->op1_type == IS_CONST) {
				key = zend_string_tolower(Z_STR_P(EX_CONSTANT(EX(opline)->op1)));
			} else if (EX(opline)->op1_type != IS_UNUSED) 	{
				ce = Z_CE_P(EX_VAR(EX(opline)->op1.var));
				if (!ce) {
					break;
				}
				key = zend_string_tolower(ce->name);
			}

			if (key && (mock = zend_hash_find(&UOPZ(mocks), key))) {
				zend_class_entry *poser;

				if (Z_TYPE_P(mock) == IS_STRING) {
					poser = zend_lookup_class(Z_STR_P(mock));
					if (!poser) {
						break;
					}
				} else poser = Z_OBJCE_P(mock);

				if (EX(opline)->op1_type == IS_CONST) {
					CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(EX(opline)->op1)), poser);
				} else {
					Z_CE_P(EX_VAR(EX(opline)->op1.var)) = poser;
				}
			}

			if (key && EX(opline)->op2_type == IS_CONST) {
				zval *function_name = EX_CONSTANT(EX(opline)->op2);
				if (EX(opline)->op1_type == IS_CONST) {
					CACHE_PTR(Z_CACHE_SLOT_P(function_name), NULL);
				} else {
					CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), NULL, NULL);
				}
			}
			
			if (key) {
				zend_string_release(key);
			}
		} break;
	}

	switch (EX(opline)->opcode) {
		case ZEND_INIT_FCALL_BY_NAME:
			if (uopz_init_fcall_by_name_handler)
				return uopz_init_fcall_by_name_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		case ZEND_INIT_FCALL:
			if (uopz_init_fcall_handler)
				return uopz_init_fcall_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		case ZEND_INIT_NS_FCALL_BY_NAME:
			if (uopz_init_ns_fcall_by_name_handler)
				return uopz_init_ns_fcall_by_name_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		case ZEND_INIT_METHOD_CALL:
			if (uopz_init_method_call_handler)
				return uopz_init_method_call_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
		case ZEND_INIT_STATIC_METHOD_CALL:
			if (uopz_init_static_method_call_handler)
				return uopz_init_static_method_call_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	return ZEND_USER_OPCODE_DISPATCH;
} /* }}} */