# PHP FFI extenesion

- Thread: https://externals.io/message/102036
- Original archive: https://news-web.php.net/php.internals/102036
- Started by Dmitry Stogov on 2018-04-13T13:27:57+00:00
- Messages: 20
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #102036 — Dmitry Stogov — 2018-04-13T13:27:57+00:00

URL: https://externals.io/message/102036#102036

Hi,


I've spent some time thinking about simple FFI for PHP, and finally, borrowed most ideas from LuaJIT.

This is an initial PoC. It was tested on Linux only.


https://github.com/dstogov/php-ffi


I would appreciate review, comments and ideas about missing features and functionality.


Thanks. Dmitry.

---

## #102037 — Arvids Godjuks — 2018-04-13T13:39:58+00:00

URL: https://externals.io/message/102036#102037 · In reply to: #102036

2018-04-13 16:27 GMT+03:00 Dmitry Stogov <dmitry@zend.com>:

> Hi,
>
>
> I've spent some time thinking about simple FFI for PHP, and finally,
> borrowed most ideas from LuaJIT.
>
> This is an initial PoC. It was tested on Linux only.
>
>
> https://github.com/dstogov/php-ffi
>
>
> I would appreciate review, comments and ideas about missing features and
> functionality.
>
>
> Thanks. Dmitry.
>
>
>
Hello Dmitry,
PECL has an extension like that listed, although it's old and probably does
not work, https://pecl.php.net/package/ffi so it might need replacing to
avoid confusion.

-- 
Arvīds Godjuks

+371 26 851 664
arvids.godjuks@gmail.com
Skype: psihius
Telegram: @psihius https://t.me/psihius

---

## #102038 — Dmitry Stogov — 2018-04-13T13:45:44+00:00

URL: https://externals.io/message/102036#102038

Hi Arvids,


I know. That extension is old and unsupported.


Anywat, currently, this is just a PoC. We will decide what to do with it, when it's more mature.


Thanks. Dmitry.

---

## #102039 — Levi Morrison — 2018-04-13T16:55:37+00:00

URL: https://externals.io/message/102036#102039 · In reply to: #102036

> I've spent some time thinking about simple FFI for PHP, and finally, borrowed most ideas from LuaJIT.
> This is an initial PoC. It was tested on Linux only.
>
> https://github.com/dstogov/php-ffi
>
> I would appreciate review, comments and ideas about missing features and functionality.

A better FFI is sorely needed so thanks for looking into this.

I don't particularly like having to manually specify the definitions.
IIRC if the DSO has debugging symbols libffi can provide them but
honestly I haven't looked at libffi in years so I might be
mis-remembering.

---

## #102043 — Stanislav Malyshev — 2018-04-16T23:49:34+00:00

URL: https://externals.io/message/102036#102043 · In reply to: #102036

Hi!

> I've spent some time thinking about simple FFI for PHP, and finally, borrowed most ideas from LuaJIT.
> 
> This is an initial PoC. It was tested on Linux only.
> 
> 
> https://github.com/dstogov/php-ffi
> 
> 
> I would appreciate review, comments and ideas about missing features and functionality.
> 

Looks interesting. On a cursory look, couple of thoughts:
- I think all the classes involved should be made non-serializable and
non-unserializable.
- Does it load shared libraries, or only uses ones already loaded? If
the former, I think there should be a way to unload them at the request
end (even though it might be performance issue, and may be not possible
if persistent resources are involved), otherwise we leak state between
requests.
- OTOH, people may want to load a set of persistent definitions from a
config file, etc. - the ffi definition probably won't change much, and
having locked down set of FFI interfaces the rest of the code is using
might be beneficial
- Since this thing is dealing with raw pointers, etc., from PHP code,
there may be a lot of crashes from using this extension in a wrong way.
I wonder which facilities we could provide for helping people to debug
it (for people who aren't super-comfortable using gdb on PHP engine).

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #102044 — Michael Wallner — 2018-04-17T05:50:34+00:00

URL: https://externals.io/message/102036#102044 · In reply to: #102043

Hi!

Nice that FFI is of interest again, so may I kindly point you to ext-psi?
https://github.com/m6w6/ext-psi


It follows a different approach, though, that it requires definition
files on startup, not at runtime.

Basically:

$ cat >time.psi <<EOF
#include <time.h>
/* time_t time(time_t *tloc); man 2 time */
function psi\time() : int {
	let tloc = NULL;
	return time(tloc) as to_int(time);
}
EOF


$ ./sapi/cli/php -d psi.directory=. -r 'var_dump(psi\time());'

It stalled the last months because I have been fighting health issues
since last summer, but I did post a link to internals about a year ago:
https://externals.io/message/98212#98259

-- 
Regards,
Mike

---

## #102045 — Dmitry Stogov — 2018-04-17T07:18:21+00:00

URL: https://externals.io/message/102036#102045

Hi!

> I've spent some time thinking about simple FFI for PHP, and finally, borrowed most ideas from LuaJIT.
>
> This is an initial PoC. It was tested on Linux only.
>
>
> https://github.com/dstogov/php-ffi
>
>
> I would appreciate review, comments and ideas about missing features and functionality.
>

Looks interesting. On a cursory look, couple of thoughts:
- I think all the classes involved should be made non-serializable and
non-unserializable.

Agree.

- Does it load shared libraries, or only uses ones already loaded? If
the former, I think there should be a way to unload them at the request
end (even though it might be performance issue, and may be not possible
if persistent resources are involved), otherwise we leak state between
requests.

I have a bit opposit idea. We will keep FFI for CLI but disable it for web apps (like `dl()`).
At the same time, we will develop a technology to preload and reuse  PHP files across requests.
And allow FFI there.

- OTOH, people may want to load a set of persistent definitions from a
config file, etc. - the ffi definition probably won't change much, and
having locked down set of FFI interfaces the rest of the code is using
might be beneficial

Yeah. Like this.

- Since this thing is dealing with raw pointers, etc., from PHP code,
there may be a lot of crashes from using this extension in a wrong way.
I wonder which facilities we could provide for helping people to debug
it (for people who aren't super-comfortable using gdb on PHP engine).

Programming using FFI, is very similar to C.
I'm not sure, if we may provide good debugging facilities.

Thanks for review.

Dmitry.


--
Stas Malyshev
smalyshev@gmail.com

Hi!

> I've spent some time thinking about simple FFI for PHP, and finally, borrowed most ideas from LuaJIT.
>
> This is an initial PoC. It was tested on Linux only.
>
>
> https://github.com/dstogov/php-ffi
>
>
> I would appreciate review, comments and ideas about missing features and functionality.
>

Looks interesting. On a cursory look, couple of thoughts:
- I think all the classes involved should be made non-serializable and
non-unserializable.
- Does it load shared libraries, or only uses ones already loaded? If
the former, I think there should be a way to unload them at the request
end (even though it might be performance issue, and may be not possible
if persistent resources are involved), otherwise we leak state between
requests.
- OTOH, people may want to load a set of persistent definitions from a
config file, etc. - the ffi definition probably won't change much, and
having locked down set of FFI interfaces the rest of the code is using
might be beneficial
- Since this thing is dealing with raw pointers, etc., from PHP code,
there may be a lot of crashes from using this extension in a wrong way.
I wonder which facilities we could provide for helping people to debug
it (for people who aren't super-comfortable using gdb on PHP engine).

--
Stas Malyshev
smalyshev@gmail.com

---

## #102046 — michal@brzuchalski.com — 2018-04-17T07:24:02+00:00

URL: https://externals.io/message/102036#102046 · In reply to: #102045

Hi Dmitry!

I am not much experienced with C but as a user, I'm just wondering if there
is a possibility to extend FFI class and autoregister all or just chosen
structs as classes, for eg.
class Libc extends FFI {
    public function __construct() {
        parent::__construct("...code", "...lib"); // tmp notation
        $this->register('struct timeval', Libc\Timeval::class); // I assume
they would extend CData
        $this->register('struct timezone', Libc\Timezone::class); // as
above
    }
}

So I can instantiate

$tz = new Libc\Timezone();
$tv = new Libc\Timeval();

and then pass them FFI function

(new Libc())->gettimeofday($tv, $tz);
var_dump($tv-tv_sec, $tv->tv_usec, $tz);

I would be able to prepare than a vendor package with a specified
autoloader.
Would that make sense?

Also wouldn't it better if CData class share the same prefixes like
FFICdata or FFI\CData?


Cheers,
Michal

2018-04-17 9:18 GMT+02:00 Dmitry Stogov <dmitry@zend.com>:

>
>
> 
> Hi!
>
> > […]
> borrowed most ideas from LuaJIT.
> > […]
> functionality.
> > […]
>
> Looks interesting. On a cursory look, couple of thoughts:
> - I think all the classes involved should be made non-serializable and
> non-unserializable.
>
> Agree.
>
> - Does it load shared libraries, or only uses ones already loaded? If
> the former, I think there should be a way to unload them at the request
> end (even though it might be performance issue, and may be not possible
> if persistent resources are involved), otherwise we leak state between
> requests.
>
> I have a bit opposit idea. We will keep FFI for CLI but disable it for web
> apps (like `dl()`).
> At the same time, we will develop a technology to preload and reuse  PHP
> files across requests.
> And allow FFI there.
>
> - OTOH, people may want to load a set of persistent definitions from a
> config file, etc. - the ffi definition probably won't change much, and
> having locked down set of FFI interfaces the rest of the code is using
> might be beneficial
>
> Yeah. Like this.
>
> - Since this thing is dealing with raw pointers, etc., from PHP code,
> there may be a lot of crashes from using this extension in a wrong way.
> I wonder which facilities we could provide for helping people to debug
> it (for people who aren't super-comfortable using gdb on PHP engine).
>
> Programming using FFI, is very similar to C.
> I'm not sure, if we may provide good debugging facilities.
>
> Thanks for review.
>
> Dmitry.
>
>
> --
> Stas Malyshev
> smalyshev@gmail.com
>
> Hi!
>
> > […]
> borrowed most ideas from LuaJIT.
> > […]
> functionality.
> > […]
>
> Looks interesting. On a cursory look, couple of thoughts:
> - I think all the classes involved should be made non-serializable and
> non-unserializable.
> - Does it load shared libraries, or only uses ones already loaded? If
> the former, I think there should be a way to unload them at the request
> end (even though it might be performance issue, and may be not possible
> if persistent resources are involved), otherwise we leak state between
> requests.
> - OTOH, people may want to load a set of persistent definitions from a
> config file, etc. - the ffi definition probably won't change much, and
> having locked down set of FFI interfaces the rest of the code is using
> might be beneficial
> - Since this thing is dealing with raw pointers, etc., from PHP code,
> there may be a lot of crashes from using this extension in a wrong way.
> I wonder which facilities we could provide for helping people to debug
> it (for people who aren't super-comfortable using gdb on PHP engine).
>
> --
> Stas Malyshev
> smalyshev@gmail.com
>



-- 
regards / pozdrawiam,
--
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com

---

## #102047 — Dmitry Stogov — 2018-04-17T07:29:26+00:00

URL: https://externals.io/message/102036#102047

hi Michael,

it's pitty, I didn't found this extension before.
thanks for pointing, I'll definetly take a look.

I, also, like the idea of preloading ffi definitions on startup, but I would prefer to allow preloading any php files. Especially for FFI, PHP wrappers would able to hide dangerous implementation details.

Thanks. Dmitry.


Hi!

Nice that FFI is of interest again, so may I kindly point you to ext-psi?
https://github.com/m6w6/ext-psi


It follows a different approach, though, that it requires definition
files on startup, not at runtime.

Basically:

$ cat >time.psi <<EOF
#include <time.h>
/* time_t time(time_t *tloc); man 2 time */
function psi\time() : int {
        let tloc = NULL;
        return time(tloc) as to_int(time);
}
EOF


$ ./sapi/cli/php -d psi.directory=. -r 'var_dump(psi\time());'

It stalled the last months because I have been fighting health issues
since last summer, but I did post a link to internals about a year ago:
https://externals.io/message/98212#98259

--
Regards,
Mike


Hi!

Nice that FFI is of interest again, so may I kindly point you to ext-psi?
https://github.com/m6w6/ext-psi


It follows a different approach, though, that it requires definition
files on startup, not at runtime.

Basically:

$ cat >time.psi <<EOF
#include <time.h>
/* time_t time(time_t *tloc); man 2 time */
function psi\time() : int {
        let tloc = NULL;
        return time(tloc) as to_int(time);
}
EOF


$ ./sapi/cli/php -d psi.directory=. -r 'var_dump(psi\time());'

It stalled the last months because I have been fighting health issues
since last summer, but I did post a link to internals about a year ago:
https://externals.io/message/98212#98259

--
Regards,
Mike

---

## #102048 — Dmitry Stogov — 2018-04-17T07:46:29+00:00

URL: https://externals.io/message/102036#102048

Hi Michal,


I didn't think in this way. I liked to make the simplest API.

I don't expect wide FFI usage in frameworks :)


BTW: I like the idea of use C type names (probably, we may reuse original C type names without additional registration).


currently we can do: $tz = $libc->new("struct timezone");


I'll think, if we can existend API to use something like: $tz = FFI::new($libc->timezone);

At least, this should eliminate C parsing overhead.


Thanks. Dmitry.

---

## #102049 — michal@brzuchalski.com — 2018-04-17T07:51:32+00:00

URL: https://externals.io/message/102036#102049 · In reply to: #102048

2018-04-17 9:46 GMT+02:00 Dmitry Stogov <dmitry@zend.com>:

> Hi Michal,
>
>
> I didn't think in this way. I liked to make the simplest API.
>
> I don't expect wide FFI usage in frameworks :)
>
>
> BTW: I like the idea of use C type names (probably, we may reuse original
> C type names without additional registration).
>
>
> currently we can do: $tz = $libc->new("struct timezone");
>

My point was ability to provide an identity to objects wich acts as a
structs. CData class has no idea of what struct type it is and I cannot
type hint over that, thats why I thought it would be usefull.
I could then prepare a vendor using pure PHP and wrap everything using
types.


>
> I'll think, if we can existend API to use something like: $tz =
> FFI::new($libc->timezone);
>
> At least, this should eliminate C parsing overhead.
>
>
> Thanks. Dmitry.
> ------------------------------
> *From:* Michał Brzuchalski <michal@brzuchalski.com>
> *Sent:* Tuesday, April 17, 2018 10:24:02 AM
> *To:* Dmitry Stogov
> *Cc:* Stanislav Malyshev; Zeev Suraski; Xinchen Hui; Nikita Popov; Bob
> Weinand; Anatol Belski (ab@php.net); PHP internals list
> *Subject:* Re: [PHP-DEV] PHP FFI extenesion
>
> Hi Dmitry!
>
> I am not much experienced with C but as a user, I'm just wondering if
> there is a possibility to extend FFI class and autoregister all or just
> chosen structs as classes, for eg.
> class Libc extends FFI {
>     public function __construct() {
>         parent::__construct("...code", "...lib"); // tmp notation
>         $this->register('struct timeval', Libc\Timeval::class); // I
> assume they would extend CData
>         $this->register('struct timezone', Libc\Timezone::class); // as
> above
>     }
> }
>
> So I can instantiate
>
> $tz = new Libc\Timezone();
> $tv = new Libc\Timeval();
>
> and then pass them FFI function
>
> (new Libc())->gettimeofday($tv, $tz);
> var_dump($tv-tv_sec, $tv->tv_usec, $tz);
>
> I would be able to prepare than a vendor package with a specified
> autoloader.
> Would that make sense?
>
> Also wouldn't it better if CData class share the same prefixes like
> FFICdata or FFI\CData?
>
>
> Cheers,
> Michal
>
> 2018-04-17 9:18 GMT+02:00 Dmitry Stogov <dmitry@zend.com>:
>
>
>
> 
> Hi!
>
> > […]
> borrowed most ideas from LuaJIT.
> > […]
> functionality.
> > […]
>
> Looks interesting. On a cursory look, couple of thoughts:
> - I think all the classes involved should be made non-serializable and
> non-unserializable.
>
> Agree.
>
> - Does it load shared libraries, or only uses ones already loaded? If
> the former, I think there should be a way to unload them at the request
> end (even though it might be performance issue, and may be not possible
> if persistent resources are involved), otherwise we leak state between
> requests.
>
> I have a bit opposit idea. We will keep FFI for CLI but disable it for web
> apps (like `dl()`).
> At the same time, we will develop a technology to preload and reuse  PHP
> files across requests.
> And allow FFI there.
>
> - OTOH, people may want to load a set of persistent definitions from a
> config file, etc. - the ffi definition probably won't change much, and
> having locked down set of FFI interfaces the rest of the code is using
> might be beneficial
>
> Yeah. Like this.
>
> - Since this thing is dealing with raw pointers, etc., from PHP code,
> there may be a lot of crashes from using this extension in a wrong way.
> I wonder which facilities we could provide for helping people to debug
> it (for people who aren't super-comfortable using gdb on PHP engine).
>
> Programming using FFI, is very similar to C.
> I'm not sure, if we may provide good debugging facilities.
>
> Thanks for review.
>
> Dmitry.
>
>
> --
> Stas Malyshev
> smalyshev@gmail.com
>
> Hi!
>
> > […]
> borrowed most ideas from LuaJIT.
> > […]
> functionality.
> > […]
>
> Looks interesting. On a cursory look, couple of thoughts:
> - I think all the classes involved should be made non-serializable and
> non-unserializable.
> - Does it load shared libraries, or only uses ones already loaded? If
> the former, I think there should be a way to unload them at the request
> end (even though it might be performance issue, and may be not possible
> if persistent resources are involved), otherwise we leak state between
> requests.
> - OTOH, people may want to load a set of persistent definitions from a
> config file, etc. - the ffi definition probably won't change much, and
> having locked down set of FFI interfaces the rest of the code is using
> might be beneficial
> - Since this thing is dealing with raw pointers, etc., from PHP code,
> there may be a lot of crashes from using this extension in a wrong way.
> I wonder which facilities we could provide for helping people to debug
> it (for people who aren't super-comfortable using gdb on PHP engine).
>
> --
> Stas Malyshev
> smalyshev@gmail.com
>
>
>
>
> --
> regards / pozdrawiam,
> --
> Michał Brzuchalski
> about.me/brzuchal
> brzuchalski.com
>



-- 
regards / pozdrawiam,
--
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com

---

## #102050 — Dmitry Stogov — 2018-04-17T08:55:03+00:00

URL: https://externals.io/message/102036#102050

Now, I got your idea.

Subclassing CData, and use that types for type hinting may make sense.

I'll put this idea in my TODO, but with low priority.


Thanks. Dmitry.

---

## #102051 — michal@brzuchalski.com — 2018-04-17T10:04:46+00:00

URL: https://externals.io/message/102036#102051 · In reply to: #102050

One more idea I can imagine - while creating FFI object would it be
possible to:
* declare all ZEND_FFI_SYM_FUNC as class methods with proper type hinting
mapped to registered classes
* declare all ZEND_FFI_SYM_VAR as class properties with some guards
* declare all ZEND_FFI_SYM_CONST as class public consts

It would be possible to use reflection then.
But that I suppose should require extending FFI and registering symbols
into newly created class_entry.
It is possible that I'm overcoming and inventing right now. If so, just
ignore me :)

2018-04-17 10:55 GMT+02:00 Dmitry Stogov <dmitry@zend.com>:

> Now, I got your idea.
>
> Subclassing CData, and use that types for type hinting may make sense.
>
> I'll put this idea in my TODO, but with low priority.
>
>
> Thanks. Dmitry.
> ------------------------------
> *From:* Michał Brzuchalski <michal@brzuchalski.com>
> *Sent:* Tuesday, April 17, 2018 10:51:32 AM
>
> *To:* Dmitry Stogov
> *Cc:* Stanislav Malyshev; Zeev Suraski; Xinchen Hui; Nikita Popov; Bob
> Weinand; Anatol Belski (ab@php.net); PHP internals list
> *Subject:* Re: [PHP-DEV] PHP FFI extenesion
>
>
>
> 2018-04-17 9:46 GMT+02:00 Dmitry Stogov <dmitry@zend.com>:
>
> Hi Michal,
>
>
> I didn't think in this way. I liked to make the simplest API.
>
> I don't expect wide FFI usage in frameworks :)
>
>
> BTW: I like the idea of use C type names (probably, we may reuse original
> C type names without additional registration).
>
>
> currently we can do: $tz = $libc->new("struct timezone");
>
>
> My point was ability to provide an identity to objects wich acts as a
> structs. CData class has no idea of what struct type it is and I cannot
> type hint over that, thats why I thought it would be usefull.
> I could then prepare a vendor using pure PHP and wrap everything using
> types.
>
>
>
> I'll think, if we can existend API to use something like: $tz =
> FFI::new($libc->timezone);
>
> At least, this should eliminate C parsing overhead.
>
>
> Thanks. Dmitry.
> ------------------------------
> *From:* Michał Brzuchalski <michal@brzuchalski.com>
> *Sent:* Tuesday, April 17, 2018 10:24:02 AM
> *To:* Dmitry Stogov
> *Cc:* Stanislav Malyshev; Zeev Suraski; Xinchen Hui; Nikita Popov; Bob
> Weinand; Anatol Belski (ab@php.net); PHP internals list
> *Subject:* Re: [PHP-DEV] PHP FFI extenesion
>
> Hi Dmitry!
>
> I am not much experienced with C but as a user, I'm just wondering if
> there is a possibility to extend FFI class and autoregister all or just
> chosen structs as classes, for eg.
> class Libc extends FFI {
>     public function __construct() {
>         parent::__construct("...code", "...lib"); // tmp notation
>         $this->register('struct timeval', Libc\Timeval::class); // I
> assume they would extend CData
>         $this->register('struct timezone', Libc\Timezone::class); // as
> above
>     }
> }
>
> So I can instantiate
>
> $tz = new Libc\Timezone();
> $tv = new Libc\Timeval();
>
> and then pass them FFI function
>
> (new Libc())->gettimeofday($tv, $tz);
> var_dump($tv-tv_sec, $tv->tv_usec, $tz);
>
> I would be able to prepare than a vendor package with a specified
> autoloader.
> Would that make sense?
>
> Also wouldn't it better if CData class share the same prefixes like
> FFICdata or FFI\CData?
>
>
> Cheers,
> Michal
>
> 2018-04-17 9:18 GMT+02:00 Dmitry Stogov <dmitry@zend.com>:
>
>
>
> 
> Hi!
>
> > […]
> borrowed most ideas from LuaJIT.
> > […]
> functionality.
> > […]
>
> Looks interesting. On a cursory look, couple of thoughts:
> - I think all the classes involved should be made non-serializable and
> non-unserializable.
>
> Agree.
>
> - Does it load shared libraries, or only uses ones already loaded? If
> the former, I think there should be a way to unload them at the request
> end (even though it might be performance issue, and may be not possible
> if persistent resources are involved), otherwise we leak state between
> requests.
>
> I have a bit opposit idea. We will keep FFI for CLI but disable it for web
> apps (like `dl()`).
> At the same time, we will develop a technology to preload and reuse  PHP
> files across requests.
> And allow FFI there.
>
> - OTOH, people may want to load a set of persistent definitions from a
> config file, etc. - the ffi definition probably won't change much, and
> having locked down set of FFI interfaces the rest of the code is using
> might be beneficial
>
> Yeah. Like this.
>
> - Since this thing is dealing with raw pointers, etc., from PHP code,
> there may be a lot of crashes from using this extension in a wrong way.
> I wonder which facilities we could provide for helping people to debug
> it (for people who aren't super-comfortable using gdb on PHP engine).
>
> Programming using FFI, is very similar to C.
> I'm not sure, if we may provide good debugging facilities.
>
> Thanks for review.
>
> Dmitry.
>
>
> --
> Stas Malyshev
> smalyshev@gmail.com
>
> Hi!
>
> > […]
> borrowed most ideas from LuaJIT.
> > […]
> functionality.
> > […]
>
> Looks interesting. On a cursory look, couple of thoughts:
> - I think all the classes involved should be made non-serializable and
> non-unserializable.
> - Does it load shared libraries, or only uses ones already loaded? If
> the former, I think there should be a way to unload them at the request
> end (even though it might be performance issue, and may be not possible
> if persistent resources are involved), otherwise we leak state between
> requests.
> - OTOH, people may want to load a set of persistent definitions from a
> config file, etc. - the ffi definition probably won't change much, and
> having locked down set of FFI interfaces the rest of the code is using
> might be beneficial
> - Since this thing is dealing with raw pointers, etc., from PHP code,
> there may be a lot of crashes from using this extension in a wrong way.
> I wonder which facilities we could provide for helping people to debug
> it (for people who aren't super-comfortable using gdb on PHP engine).
>
> --
> Stas Malyshev
> smalyshev@gmail.com
>
>
>
>
> --
> regards / pozdrawiam,
> --
> Michał Brzuchalski
> about.me/brzuchal
> brzuchalski.com
>
>
>
>
> --
> regards / pozdrawiam,
> --
> Michał Brzuchalski
> about.me/brzuchal
> brzuchalski.com
>



-- 
regards / pozdrawiam,
--
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com

---

## #102075 — Michael Wallner — 2018-04-26T07:31:28+00:00

URL: https://externals.io/message/102036#102075 · In reply to: #102047

Hey Dmitry!


> hi Michael,
> 
> it's pitty, I didn't found this extension before.
> thanks for pointing, I'll definetly take a look.

Did you have a chance to look at it yet?


> I, also, like the idea of preloading ffi definitions on startup, but I
> would prefer to allow preloading any php files. Especially for FFI, PHP
> wrappers would able to hide dangerous implementation details.
> 

I'm not sure the one depends on the other, and how would that be
different to opcache?

With PSI everything related C is encapsulated, you cannot change
anything regarding the access or calling scheme at runtime.

I admit, PSI is far away from being optimized or even finished yet, but
there are a few important key differentiation points:

- the system administrator controls FFI
- parses C headers, no need to duplicate declarations
- function call and data access is pre-defined, not at runtime

-- 
Regards,
Mike

---

## #102076 — Dmitry Stogov — 2018-04-26T09:25:37+00:00

URL: https://externals.io/message/102036#102076

hi Michael,



Hey Dmitry!


> hi Michael,
>
> it's pitty, I didn't found this extension before.
> thanks for pointing, I'll definetly take a look.

Did you have a chance to look at it yet?

Yeah. I took a look through API and implementation, but didn't try to use it in action.
I exited by the amount of work you did, and see advantages in your approach,
but in general, I like to provide a bit different thing.

Acttually, my FFI extension inspired by LuaJit implementation (copied by Python cffi ABI mode).
I prefer exteremely simple API, simple and compact implementation. I especially, selected run-time binding, because plan to integrate FFI with JIT (main advantage of LuaJit).

[see below]



> I, also, like the idea of preloading ffi definitions on startup, but I
> would prefer to allow preloading any php files. Especially for FFI, PHP
> wrappers would able to hide dangerous implementation details.
>

I'm not sure the one depends on the other, and how would that be
different to opcache?

With PSI everything related C is encapsulated, you cannot change
anything regarding the access or calling scheme at runtime.

I admit, PSI is far away from being optimized or even finished yet, but
there are a few important key differentiation points:

- the system administrator controls FFI
- parses C headers, no need to duplicate declarations
- function call and data access is pre-defined, not at runtime

Yeah. I see these differences. Reuse of system headers is definitely a big advantage.
Pre-loading and absence of run-time definition, is good from security poin of view, but makes usage a bit more complex. The thing, I don't like, is a special binding language.

Most probably, both FFI and PSI might be better, taking ideas from the other...

Did you use PSI with some complex libraries?

Thanks. Dmitry.


--
Regards,
Mike


Hey Dmitry!


> hi Michael,
>
> it's pitty, I didn't found this extension before.
> thanks for pointing, I'll definetly take a look.

Did you have a chance to look at it yet?


> I, also, like the idea of preloading ffi definitions on startup, but I
> would prefer to allow preloading any php files. Especially for FFI, PHP
> wrappers would able to hide dangerous implementation details.
>

I'm not sure the one depends on the other, and how would that be
different to opcache?

With PSI everything related C is encapsulated, you cannot change
anything regarding the access or calling scheme at runtime.

I admit, PSI is far away from being optimized or even finished yet, but
there are a few important key differentiation points:

- the system administrator controls FFI
- parses C headers, no need to duplicate declarations
- function call and data access is pre-defined, not at runtime

--
Regards,
Mike

---

## #102079 — Dmitry Stogov — 2018-04-26T18:47:45+00:00

URL: https://externals.io/message/102036#102079

Hi Michael,


I've just tried to run PSI with php-master (32-bit DEBUG build) and got `SIGSEGV` on the simplest test.

Use "psi.d/string.psi" and attemt to call psi\strerror(10)


#0  0xf44916ba in psi_call_frame_parse_args (frame=0xf426c500, execute_data=0x0) at /home/dmitry/php/ext-psi/src/call.c:273
#1  0xf4494fe7 in psi_context_call (C=0x92dfe90, execute_data=0x0, return_value=0x8fc0144 <HARDCODED_INI+4>, impl=0x9341658)
    at /home/dmitry/php/ext-psi/src/context.c:250
#2  0xf4499b44 in psi_ffi_handler (sig=0x92e0fa0, result=0xffff9760, args=0xffff96f0, data=0x9341658)
    at /home/dmitry/php/ext-psi/src/libffi.c:387
#3  0xf4467a76 in ffi_closure_SYSV_inner () from /lib/libffi.so.6
#4  0xf4467eb6 in ffi_closure_SYSV () from /lib/libffi.so.6
#5  0x08701d21 in ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER () at /home/dmitry/php/php-master/Zend/zend_vm_execute.h:890
#6  0x0875fd12 in execute_ex (ex=0xf421d020) at /home/dmitry/php/php-master/Zend/zend_vm_execute.h:54819
#7  0x087643b1 in zend_execute (op_array=0xf426c460, return_value=0x0) at /home/dmitry/php/php-master/Zend/zend_vm_execute.h:59987
#8  0x086b0d2f in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/dmitry/php/php-master/Zend/zend.c:1566
#9  0x0863cdde in php_execute_script (primary_file=0xffffcbbc) at /home/dmitry/php/php-master/main/main.c:2467
#10 0x0876676a in do_cli (argc=2, argv=0x90e4850) at /home/dmitry/php/php-master/sapi/cli/php_cli.c:1011
#11 0x087673b2 in main (argc=2, argv=0x90e4850) at /home/dmitry/php/php-master/sapi/cli/php_cli.c:1404

execute_data is `NULL` 


Did you test ext-psi with php-master?


As I understood, you create libffi callback/closure for each function declared in *.psi file(s).

And then use it to call a general psi_ffi_handler().

Why not to call a general function handler in first place (without any ffi magic)?


Thanks. Dmitry.

---

## #102080 — Michael Wallner — 2018-04-26T19:30:38+00:00

URL: https://externals.io/message/102036#102080 · In reply to: #102079

Hey!

> 
> 
> Hi Michael,
> 
> 
> I've just tried to run PSI with php-master (32-bit DEBUG build) and got `SIGSEGV` on the simplest test.
> 
> Use "psi.d/string.psi" and attemt to call psi\strerror(10)
> 
> 
> #0  0xf44916ba in psi_call_frame_parse_args (frame=0xf426c500, execute_data=0x0) at /home/dmitry/php/ext-psi/src/call.c:273
> #1  0xf4494fe7 in psi_context_call (C=0x92dfe90, execute_data=0x0, return_value=0x8fc0144 <HARDCODED_INI+4>, impl=0x9341658)
>    at /home/dmitry/php/ext-psi/src/context.c:250
> #2  0xf4499b44 in psi_ffi_handler (sig=0x92e0fa0, result=0xffff9760, args=0xffff96f0, data=0x9341658)
>    at /home/dmitry/php/ext-psi/src/libffi.c:387
> #3  0xf4467a76 in ffi_closure_SYSV_inner () from /lib/libffi.so.6
> #4  0xf4467eb6 in ffi_closure_SYSV () from /lib/libffi.so.6
> #5  0x08701d21 in ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER () at /home/dmitry/php/php-master/Zend/zend_vm_execute.h:890
> #6  0x0875fd12 in execute_ex (ex=0xf421d020) at /home/dmitry/php/php-master/Zend/zend_vm_execute.h:54819
> #7  0x087643b1 in zend_execute (op_array=0xf426c460, return_value=0x0) at /home/dmitry/php/php-master/Zend/zend_vm_execute.h:59987
> #8  0x086b0d2f in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/dmitry/php/php-master/Zend/zend.c:1566
> #9  0x0863cdde in php_execute_script (primary_file=0xffffcbbc) at /home/dmitry/php/php-master/main/main.c:2467
> #10 0x0876676a in do_cli (argc=2, argv=0x90e4850) at /home/dmitry/php/php-master/sapi/cli/php_cli.c:1011
> #11 0x087673b2 in main (argc=2, argv=0x90e4850) at /home/dmitry/php/php-master/sapi/cli/php_cli.c:1404
> 
> execute_data is `NULL` 
> 
> 
> Did you test ext-psi with php-master?
> 

I only test on master, but never tested 32bit :-/
https://travis-ci.org/m6w6/ext-psi/jobs/368760446#L2102

> 
> As I understood, you create libffi callback/closure for each function declared in *.psi file(s).
> 
> And then use it to call a general psi_ffi_handler().
> 
> Why not to call a general function handler in first place (without any ffi magic)?
> 

Let me think about that. It’s my first with libffi/libjit, so maybe I was thinking too complicated and took more corners than I had to…

Thanks,
Mike

---

## #102081 — Michael Wallner — 2018-04-26T19:33:19+00:00

URL: https://externals.io/message/102036#102081 · In reply to: #102076

> 
> 
> 
> Did you use PSI with some complex libraries?

Define complex. There’s a working sqlite test (quite simple use case for sqlite, though):
https://github.com/m6w6/ext-psi/blob/master/tests/sqlite/sqlite001.phpt <https://github.com/m6w6/ext-psi/blob/master/tests/sqlite/sqlite001.phpt>

Thanks,
Mike

---

## #102083 — Dmitry Stogov — 2018-04-26T22:29:48+00:00

URL: https://externals.io/message/102036#102083

Hi Michael,


I've, also, tried to implement FFI definition pre-loading (currently just H files).

I spent just two hours and implementation misses a lot of details, but it looks like this may work with FFI extension almost out of the box.


https://github.com/dstogov/php-ffi/commit/75cdae7a26406ae75ee27317ddb1981774a81006


Thanks. Dmitry.

---

## #102084 — Dmitry Stogov — 2018-04-27T13:47:44+00:00

URL: https://externals.io/message/102036#102084

Pre-loading of *.h files is fully functional now. See tests/300.phpt
