-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[VarDumper] Add FFI\CData
and FFI\CType
types
#46773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hey! I see that this is your first PR. That is great! Welcome! Symfony has a contribution guide which I suggest you to read. In short:
Review the GitHub status checks of your pull request and try to solve the reported issues. If some tests are failing, try to see if they are failing because of this change. When two Symfony core team members approve this change, it will be merged and you will become an official Symfony contributor! I am going to sit back now and wait for the reviews. Cheers! Carsonbot |
I wanted to do that for a while. But you add a really better caster than what I have ever dreamed. This is very nice. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice, thanks!
Here is some nitpicking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time on your patch and submitted a few changes to your fork. Please fetch + reset --hard
before opening it again π¬
$ptr = $type->getPointerType(); | ||
|
||
if (null === $data) { | ||
return [Caster::PREFIX_VIRTUAL.'0' => $ptr]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand what this is about, can you please add a test case to cover it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand what this is about
Any pointer contains inside a link to where it points and at least one element:
// C
int *getArray()
{
int *array = new int[42];
array[0] = 1;
array[1] = 2;
return array;
}
// >> \FFI::cdef()
extern int *getArray(void);
// >> PHP
$data = $ffi->getArray();
dump($data);
// >> VarDumper representation
FFI\CData<int32_t*> { #0
0: FFI\CData<int32_t> { #1
+cdata: 1
}
}
Although the size and type of the memory area where the pointer refers is not known (I propose to provide an alternative for void*
, a pointer to something undefined) in advance, there is at least a zero element there (if the memory area is available).
In this case, if the CData
was not transferred, a structure based on the type will be formed:
FFI\CType<int32_t*> { #0
0: FFI\CType<int32_t> { #1 }
}
We can also get where the pointer "points" to via array access:
echo $data[0]->cdata; // 1
// OR (magic of FFI: alternative, but not strict option)
echo $data->cdata; // 1
Ok, ill add a tests
return match ($ptr->getKind()) { | ||
CType::TYPE_CHAR => [Caster::PREFIX_VIRTUAL.'cdata' => self::castFFIStringValue($data)], | ||
CType::TYPE_FUNC => self::castFFIFunction($stub, $ptr), | ||
default => [Caster::PREFIX_VIRTUAL.'cdata' => $data[0]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be a dumb question as I don't know FFI much, by why $data[0]
? Is this tested?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I noted above, this is getting real data by a pointer to this data: $data->getType(); // int*
and $data[0]->getType(); // int
No, there are no tests for pointers. Can be added, no problem.
|
||
$string = implode('', $result); | ||
$stub = new CutStub($string); | ||
$stub->cut = -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replace the custom truncation by a CutStub
.
Can't we know the size of the truncated data btw?
I think this is also not tested, isn't it? Can it be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we know the size of the truncated data btw?
In most cases, strings contain a trailing \0
(or \0\0
in wchar_t
). This is how, for example, the function FFI::string($pointerToChar); // "string\0"
works.
However, this is not entirely safe, since the function can return strings without the terminating \0
, and store the length separately:
struct CustomString {
char* data;
int length;
}
In this case, while we are reading the data from char
array, we can get into the "junk memory" or get an Access Violation or Segmentation Fault errors (https://en.wikipedia.org/wiki/Segmentation_fault). Therefore, there is a limit on the length of the line, so that even when reading extra data, we can stop in time.
No, this has only been tested in manual mode. You are right, we need to add to this too.
|
||
return match ($ptr->getKind()) { | ||
CType::TYPE_CHAR => [Caster::PREFIX_VIRTUAL.'cdata' => self::castFFIStringValue($data)], | ||
CType::TYPE_FUNC => self::castFFIFunction($stub, $ptr), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I understand, a pointer pointing to a function is going to be dumped the same as dumping a function.
Did I get this right? Shouldn't we make a difference between both?
Do we have the same concern for other kind of pointed values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I understand, a pointer pointing to a function is going to be dumped the same as dumping a function.
Yep. However, a function is always a pointer to it (seemingly o___0).
It looks something like:
$pointer = function () { ... };
The variable contains a reference to a function (i.e. a pointer to it), but just like that, a function does not exist without a pointer to it.
Maybe I'm wrong on this. Need a C/C++ specialist, which I am not :D
Do we have the same concern for other kind of pointed values?
Perhaps arrays with a predetermined size π€
Done. Perhaps it makes sense to remove the alignment from the output? I have not yet come across cases where this information would be needed. |
FFI\CData
and FFI\CType
types
@lyrixx ping? =) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ππΌ Super cool. Thanks
Thank you @SerafimArts. |
Added support of FFI:
Before
After
P.S. I apologize for the multiple force pushes, errors in tests and codestyle have been fixed.
Review And TODOs
char*
tests (with\0
and without\0
).