X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=README.md;h=6c91e51a544b0e123fa46620ebade912934e97f1;hp=bfdb40c67b5c8540becfb3ddaee2a3d961239c6d;hb=9d039c3e02435dafc558b8524d8e3728d2e5a704;hpb=39831a9cf4a4aa9f126bc9a949f03ae232e3794b diff --git a/README.md b/README.md index bfdb40c..6c91e51 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,320 @@ # ext-psi -[![Build Status](https://travis-ci.org/m6w6/psi.svg?branch=master)](https://travis-ci.org/m6w6/psi) +[![Join the chat at https://gitter.im/m6w6/ext-psi](https://badges.gitter.im/m6w6/ext-psi.svg)](https://gitter.im/m6w6/ext-psi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.org/m6w6/ext-psi.svg?branch=master)](https://travis-ci.org/m6w6/ext-psi) -... +PSI is a PHP extension, which provides a foreign function interface through +`libffi` and/or `libjit`. -## Documentation +The acronym PSI may be read as: +* PHP System Interface -See the [online markdown reference](https://mdref.m6w6.name/psi). +> **WARNING:** +> This is heavy WIP. -Known issues are listed in [BUGS](./BUGS) and future ideas can be found in [TODO](./TODO). +## Features + +* structs, unions, enums and typedefs +* numeric and boolean expressions +* scalar constants +* vararg calls ## Installing +> **WARNING:** +> This is heavy WIP. Installation only works from a source checkout with php-src@master yet. + ### PECL +This extension is distributed through [PECL](http://pecl.php.net) and can be +installed with [PEAR](http://pear.php.net)'s pecl command: + pecl install psi ### PHARext Watch out for [PECL replicates](https://replicator.pharext.org?psi) -and pharext packages attached to [releases](./releases). +and [pharext](https://github.com/pharext) packages attached to +[releases](https://github.com/m6w6/ext-psi/releases). ### Checkout +This extension is hosted at [Github](https://github.com/m6w6/ext-psi) with a +personal [mirror](https://git.m6w6.name/?p=m6w6/ext-psi) available. + git clone github.com:m6w6/ext-psi + cd ext-psi + /path/to/phpize ./configure --with-php-config=/path/to/php-config make sudo make install +## Configuring PSI at build time + +PSI supports the following configure switches: + +### --enable-psi +**Enable PHP System Interface support.** + +This is only relevant for an in-tree build. Use `--enable-psi` to include +the PSI extension in the build. + +### --with-psi-libjit +**Path to libjit.** + +> **WARNING:** +> We currently rely on a patched libjit, because of an apparent bug in how +> libjit creates closures, which still needs to be verified, though. +> See https://github.com/m6w6/libjit for the preliminary patch. + +### --with-psi-libffi +**Path to libffi.** + +## Configuring PSI at runtime + +### psi.engine + +The backend that PSI should use as FFI, either _jit_ for `libjit` or _ffi_ for `libffi`. Defaults to "ffi". + +### psi.directory + +A colon separated list of directories to scan for `*.psi` files. Defaults to "psi.d". + +### psi.blacklist.decls + +A comma separated list of C function declarations to ignore. + +### psi.blacklist.vars + +A comma separated list of C variable declarations to ignore. + +## PSI files + +### CPP + +* conditional parsing +* including headers + +```c +#include +``` + +### Comments + +* C style multi line comments +* C++ style single line comments + +```c +// this is a one line comment +/* followed + by a multi + line comment +*/ +``` + +### Typedefs + +```c +typedef unsigned char xmlChar; +``` + +They follow the basic C-style `typedef` syntax. + +```c +typedef struct str { + char *p; + size_t l; +} str_t; +``` +You can also `typedef` unions and enums that way. + +### Structs + +The following example results in exactly the same interpretation as the previous: + +```c +typedef struct str str_t; +struct str { + char *p; + size_t l; +} +``` + +A struct will have the size of all its elements plus padding combined and an +alignment equal to that of the largest element's alignment. + +### Enums + +Enums are considered to be of type `int`. + +```c +enum STATUS { + FAILURE = -1, + SUCCESS +} +``` + +Enums will be registered as userland constants with the following pattern: + +* `psi\STATUS\FAILURE` with value -1 +* `psi\STATUS\SUCCESS` with value 0 + +### Unions + +```c +union anyval { + char c; + short s; + int i; + long l; + float f; + double d; + str_t str; +} +``` + +Unions will have the size and alignment of the largest element they contain. + +### Lib + +```c +lib "awesome"; +``` + +These statements define what library should be `dlopen()`-ed to look up symbols from declarations. +When a `lib` statement is omitted, stdlib is assumed. + +### Declarations + +Declarations provide all information needed to make a foreign function call. + +```c +extern char *strerror(int errnum); +``` + +You may specify a non-standard calling convention in place of `extern`, where `default` and `cdecl` have the same meaning as `extern`. + +Additionally recognized calling conventions include: `stdcall` and `fastcall`. + +### Constants + +```c +const int num\ZERO = 0; +const string pwd\TOKEN = "4WlOjXGL"; +``` + +Constants must have a namespaced identifiers and are registered as userland constants. + +### Implementations + +Implementations are the userland visible interfaces to the foreign function interface. + +```php +function str\error(int $num) : string { + let errnum = intval($num); + return to_string(strerror); +} +``` + +Each implementation refers to exactly one declared foreign function referenced in its `return` statement. Each declaration, on the other hand, may have any number of implementations. + +## Complete example + +```c +// all declarations in this file should be looked up in libidn +lib "idn"; + +// IDNA errors +const int \IDNA_SUCCESS = 0; +const int \IDNA_STRINGPREP_ERROR = 1; +const int \IDNA_PUNYCODE_ERROR = 2; +const int \IDNA_CONTAINS_NON_LDH = 3; +const int \IDNA_CONTAINS_LDH = 3; +const int \IDNA_CONTAINS_MINUS = 4; +const int \IDNA_INVALID_LENGTH = 5; +const int \IDNA_NO_ACE_PREFIX = 6; +const int \IDNA_ROUNDTRIP_VERIFY_ERROR = 7; +const int \IDNA_CONTAINS_ACE_PREFIX = 8; +const int \IDNA_ICONV_ERROR = 9; +const int \IDNA_MALLOC_ERROR = 201; +const int \IDNA_DLOPEN_ERROR = 202; +// IDNA flags +const int \IDNA_ALLOW_UNASSIGNED = 1; +const int \IDNA_USE_STD3_ASCII_RULES = 2; + +// nothing special about the declaration here +default int idna_to_ascii_8z(char *host, char **buffer, int flags); + +function idn\utf8_to_ascii(string $host, string &$result, int $flags = 0) : int { + // there must be a `let` statement for each + // declared argument of the called function + + // setup a pointer to NULL + let buffer = &NULL; + + // setup a string pointer to $host + let host = strval($host); + + // assing the integer value of $flags + let flags = intval($flags); + + // the function to call is referenced in + // the return statement, along with the + // neccessary cast how to interpred the + // returned native value + return to_int(idna_to_ascii_8z); + + // by-ref vars might receive output values + // through `set` statments, which also + // require a cast how to marshal the + // native data as PHP value + set $result = to_string(*buffer); + + // after the buffer has been marshaled + // for the PHP engine, we have to free + // the buffer to avoid a memory leak + free free(*buffer); + // note that in this example we omit the + // declaration of the free() function called + // in our `free` statement for brevity +} + +default char *idna_strerror(int rc); +function idn\strerror(int $rc) : string { + return to_string(idna_strerror); + let rc = intval($rc); +} +``` + +### Userland + +```php +$rc = idn\utf8_to_ascii("flöte.de", $result); +printf("<%s>\n", $result); +printf("%s\n", idn\strerror($rc)); + +$rc = idn\utf8_to_ascii("…asdf….de", $result, IDNA_USE_STD3_ASCII_RULES); +printf("<%s>\n", $result); +printf("%s\n", idn\strerror($rc)); +``` + +#### Output +``` + +Success +<> +Non-digit/letter/hyphen in input +``` + ## ChangeLog A comprehensive list of changes can be obtained from the [PECL website](https://pecl.php.net/package-changelog.php?package=psi). +Known issues are listed in [BUGS](./BUGS) and future ideas can be found in [TODO](./TODO). + ## License ext-psi is licensed under the 2-Clause-BSD license, which can be found in