Skip to content

Conversation

@Girgias
Copy link
Member

@Girgias Girgias commented May 31, 2024

Looks like this information is never set anywhere for internal functions/methods that return by reference.

EDIT: I'm not exactly sure that's the correct fix even if it looks like it, because I'm still running into some issues for Girgias#19

Copy link
Member

@kocsismate kocsismate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! A test in zend_test may be useful, but I'm also fine with the PR as-is.

Copy link
Member

@kocsismate kocsismate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just seen your edit: in case of doubt, a test is definitely useful.

Also, I've just found this:

https://github.com/php/php-src/blob/c2a9166ef09df59772bf9d4c42414c9daa64e426/Zend/zend_API.h#L126-L125 based on which it looks like the flag should be set via arginfo.

And later, the ZEND_ACC_RETURN_REFERENCE flag is applied here:

internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE;

(I only found these code paths based on a very quick search, so please take it with a grain of salt ^^)

@kocsismate
Copy link
Member

Further evidence I found: https://github.com/kocsismate/php-src/blob/c2a9166ef09df59772bf9d4c42414c9daa64e426/Zend/zend_API.h#L201 The returns_reference should be set properly when generating arginfo.

@Girgias Girgias force-pushed the gen_stub_by_ref_return branch from 8266bb5 to 65e32f2 Compare June 6, 2024 16:08
@Girgias
Copy link
Member Author

Girgias commented Jun 6, 2024

Turns out the flag is already set, however I have no god-damn clue how one is mean to actually create a reference to some zval* that is usable for userland.

Even copying VM APIs seems to not do what I would expect it to do. So if anyone has any idea how to reliably implement this without using an INDIRECT zval I would love to hear the solution.

@morrisonlevi
Copy link
Contributor

morrisonlevi commented Jun 6, 2024

I'm not quite sure I understand your problem. I would mimic ZEND_RETURN_BY_REF:

	// retval_ptr is basically OP1
	if (Z_ISREF_P(retval_ptr)) {
		Z_ADDREF_P(retval_ptr);
	} else {
		ZVAL_MAKE_REF_EX(retval_ptr, 2);
	}
	ZVAL_REF(return_value, Z_REF_P(retval_ptr));

@Girgias
Copy link
Member Author

Girgias commented Jun 6, 2024

I'm not quite sure I understand your problem. I would mimic ZEND_RETURN_BY_REF:

	// retval_ptr is basically OP1
	if (Z_ISREF_P(retval_ptr)) {
		Z_ADDREF_P(retval_ptr);
	} else {
		ZVAL_MAKE_REF_EX(retval_ptr, 2);
	}
	ZVAL_REF(return_value, Z_REF_P(retval_ptr));

This does not seem to work.

@nielsdos
Copy link
Member

nielsdos commented Jun 6, 2024

@Girgias Girgias closed this Jun 11, 2024
@Girgias
Copy link
Member Author

Girgias commented Jun 11, 2024

Turns out we already support this and my code was just wrong, because references are weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants