Beispiel #1
0
static int32_t qb_transfer_variables_to_generator(qb_interpreter_context *cxt) {
	USE_TSRM
	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
	zval *ret, *ret_key;

	// reusing previous key and value
	if(generator->value) {
		ret = generator->value;
	} else {
		ALLOC_INIT_ZVAL(ret);
		generator->value = ret;
	}
	if(generator->key) {
		ret_key = generator->key;
	} else {
		ALLOC_INIT_ZVAL(ret_key);
		generator->key = ret_key;
	}

	if(cxt->function->return_variable->address) {
		if(!qb_transfer_value_to_zval(cxt->function->local_storage, cxt->function->return_variable->address, ret)) {
			uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
			qb_append_exception_variable_name(cxt->function->return_variable TSRMLS_CC);
			qb_set_exception_line_id(line_id TSRMLS_CC);
			return FALSE;
		}
	}
	if(cxt->function->return_key_variable->address) {
		if(!qb_transfer_value_to_zval(cxt->function->local_storage, cxt->function->return_key_variable->address, ret_key)) {
			uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
			qb_append_exception_variable_name(cxt->function->return_key_variable TSRMLS_CC);
			qb_set_exception_line_id(line_id TSRMLS_CC);
			return FALSE;
		}
	}
	if(cxt->function->sent_variable->address) {
#if PHP_MINOR_VERSION > 5 || PHP_RELEASE_VERSION > 7
		static zval _dummy_value, *dummy_value = &_dummy_value;
		if(generator->send_target) {
			zval_ptr_dtor(generator->send_target);
		}
		generator->send_target = (zval **) &cxt->send_target;

		// Zend will call Z_DELREF_PP() on what generator->send_target points to
		// put a dummy value there so it doesn't crash
		*generator->send_target = dummy_value;
#else
		if(!generator->send_target) {
			cxt->send_target = emalloc(sizeof(temp_variable));
			memset(cxt->send_target, 0, sizeof(temp_variable));
			generator->send_target = cxt->send_target;
		}
#endif
	}
	return TRUE;
}
Beispiel #2
0
static int32_t qb_transfer_arguments_to_php(qb_interpreter_context *cxt) {
	USE_TSRM
#if !ZEND_ENGINE_2_2 && !ZEND_ENGINE_2_1
	void **p = EG(current_execute_data)->prev_execute_data->function_state.arguments;
#else
	void **p = EG(argument_stack).top_element-1-1;
#endif
	uint32_t received_argument_count = (uint32_t) (uintptr_t) *p;
	uint32_t i;

	// copy changes to by-ref arguments
	for(i = 0; i < cxt->function->argument_count; i++) {
		qb_variable *qvar = cxt->function->variables[i];

		if(qvar->flags & QB_VARIABLE_BY_REF) {
			if(i < received_argument_count) {
				zval **p_zarg = (zval**) p - received_argument_count + i;
				zval *zarg = *p_zarg;
				if(!qb_transfer_value_to_zval(cxt->function->local_storage, qvar->address, zarg)) {
					uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
					qb_append_exception_variable_name(qvar TSRMLS_CC);
					qb_set_exception_line_id(line_id TSRMLS_CC);
					return FALSE;
				}
			}
		}
		qvar->value = NULL;
	}

	if(EG(return_value_ptr_ptr)) {
		// copy value into return variable
		zval *ret, **p_ret = EG(return_value_ptr_ptr);
		ALLOC_INIT_ZVAL(ret);
		*p_ret = ret;
		if(cxt->function->return_variable->address) {
			if(!qb_transfer_value_to_zval(cxt->function->local_storage, cxt->function->return_variable->address, ret)) {
				uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
				qb_append_exception_variable_name(cxt->function->return_variable TSRMLS_CC);
				qb_set_exception_line_id(line_id TSRMLS_CC);
				return FALSE;
			}
		}
	}
	return TRUE;
}
Beispiel #3
0
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) {
	int32_t result = TRUE;
	if(ivar->flags & QB_VARIABLE_IMPORTED) {
		USE_TSRM
		zval *zvalue = ivar->value, **p_zvalue = ivar->value_pointer;
		if(!IS_READ_ONLY(ivar->address)) {
			if(zvalue) {
				// separate the zval first, since we're modifying it
				SEPARATE_ZVAL_IF_NOT_REF(&zvalue);
			} else {
				ALLOC_INIT_ZVAL(zvalue);
			}
			if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) {
				uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
				qb_append_exception_variable_name(ivar TSRMLS_CC);
				qb_set_exception_line_id(line_id TSRMLS_CC);
				result = FALSE;
			}

			if(p_zvalue) {
				*p_zvalue = zvalue;
			} else {
				if(ivar->flags & QB_VARIABLE_GLOBAL) {
					zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL);
				} else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) {
					zval *container = scope->object;
					zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC);
					Z_OBJ_WRITE_PROP(container, name, zvalue);
				}
			}
		}
		if(!p_zvalue && zvalue) {
			// if p_zvalue isn't null, then something else has put a refcount 
			// on the zval (and we didn't increment it earlier)
			zval_ptr_dtor(&zvalue);
		}
		ivar->value_pointer = NULL;
		ivar->value = NULL;
		ivar->flags &= ~QB_VARIABLE_IMPORTED;
	}
	return result;
}
Beispiel #4
0
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) {
	int32_t result = TRUE;
	if(ivar->flags & QB_VARIABLE_IMPORTED) {
		USE_TSRM
		if(!READ_ONLY(ivar->address)) {
			zval *zvalue;
			if(ivar->value_pointer) {
				zvalue = *ivar->value_pointer;
			} else {
				zvalue = ivar->value;
				// separate the zval first, since we're modifying it
				SEPARATE_ZVAL_TO_MAKE_IS_REF(&zvalue);
			}
			if(!zvalue) {
				ALLOC_INIT_ZVAL(zvalue);
				if(ivar->value_pointer) {
					*ivar->value_pointer = zvalue;
				}
			}
			if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) {
				uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
				qb_set_exception_line_id(line_id TSRMLS_CC);
				result = FALSE;
			}

			if(!ivar->value_pointer) {
				if(ivar->flags & QB_VARIABLE_GLOBAL) {
					zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL);
				} else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) {
					zval *container = scope->zend_object;
					zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC);
					Z_OBJ_WRITE_PROP(container, name, zvalue);
					zval_ptr_dtor(&zvalue);
				}
			}
			ivar->value_pointer = NULL;
			ivar->value = NULL;
		}
		ivar->flags &= ~QB_VARIABLE_IMPORTED;
	}