Affix
view release on metacpan or search on metacpan
by [Raku's `native` trait](https://docs.raku.org/language/nativecall).
A simple example would look like this:
```perl
use Affix;
sub some_argless_function :Native('something');
some_argless_function();
```
The first line imports various code attributes and types. The next line looks
like a relatively ordinary Perl sub declaration--with a twist. We use the
`:Native` attribute in order to specify that the sub is actually defined in a
native library. The platform-specific extension (e.g., .so or .dll), as well as
any customary prefixes (e.g., lib) will be added for you.
The first time you call "some\_argless\_function", the "libsomething" will be
loaded and the "some\_argless\_function" will be located in it. A call will then
be made. Subsequent calls will be faster, since the symbol handle is retained.
Of course, most functions take arguments or return values--but everything else
], } dob;
name => Str, char *name;
wId => Long long wId;
]; };
```
A struct consists of a sequence of members with storage allocated in an ordered
sequence (as opposed to `Union`, which is a type consisting of a sequence of
members where storage overlaps).
A C struct that looks like this:
```
struct {
char *make;
char *model;
int year;
};
```
...would be defined this way:
A union is a type consisting of a sequence of members with overlapping storage
(as opposed to `Struct`, which is a type consisting of a sequence of members
whose storage is allocated in an ordered sequence).
The value of at most one of the members can be stored in a union at any one
time and the union is only as big as necessary to hold its largest member
(additional unnamed trailing padding may also be added). The other members are
allocated in the same bytes as part of that largest member.
A C union that looks like this:
```
union {
char c[5];
float f;
};
```
...would be defined this way:
dyncall/ToDo view on Meta::CPAN
- find big endian arm box (also hardfloat), e.g. cubietruck: http://blog.netbsd.org/tnf/entry/working_arm_multiprocessor_support
- test if armhf/thumb is actually working... pulls in arm mode code in dyncall_callvm.c
- dyncall_call_mips_n32.h and dyncall_call_mips_n64.h are pretty much the same, share code
- support for return values: aggregate return values on non-x64
- support for argument values: aggregates on non-x64, vector types, long double (c89)
* make sure that struct support for ellipsis calls are not forgotten (copy everything by value)
- support for argument values: _Complex (c99)
- support for argument values: Fixed-width integer types (c99) - could be just aliases but would help abstracting it away from library users
- other syscalls
- test MIPS32 eabi big endian (current port works on psp, which is little endian)
- implement MIPS64 N32 (gcc -mabi=n32); both, little and big-endian (looks like NetNBSD on and
EdgeRouter lite uses this: https://blog.netbsd.org/tnf/entry/hands_on_experience_with_edgerouter)
- MIPS64 n32 softfloat support (-msoft-float)
- implement MIPS64 EABI (gcc -mabi=eabi); both, little and big-endian
- support for Minix/arm
- improve ellipsis test:
* test not just with one fixed arg, to also simulate alignment problems
* test return values
* convert from c++ to c, to have it also on plan9, and more portability
dynload:
dyncall/ToDo view on Meta::CPAN
dynload_syms_elf.c:164: error: `DT_SYMTAB' undeclared (first use in this function)
dynload_syms_elf.c:165: error: `DT_HASH' undeclared (first use in this function)
make: *** [dynload_syms.o] Error 1
dyncallback:
------------
- callback_plain's return value not correct anymore on NDS (maybe just broken testcode?),
see above under 1.1 items
* check other platforms also, if asm stub initializes retval space, correctly
- test MIPS32 eabi big endian (current port works on psp, which is little endian)
- implement MIPS64 N32 (gcc -mabi=n32); both, little and big-endian (looks like NetNBSD on and
EdgeRouter lite uses this: https://blog.netbsd.org/tnf/entry/hands_on_experience_with_edgerouter)
- MIPS64 n32 softfloat support (-msoft-float)
- implement MIPS64 EABI (gcc -mabi=eabi); both, little and big-endian
- support for Minix/arm
bindings:
---------
- release bindings as standalone packages (already done for rbdc as a gem and rdyncall on cran)
* add note to documentation, where bindings are
- add rdoc documentation to ruby gem
dyncall/doc/disas_examples/x86.plan9call.disas view on Meta::CPAN
0010b0 c7042400000000 (16) MOVL $0,(SP) ; arg 0 -> "push" onto stack
0010b7 b801000000 (16) MOVL $1,AX ; arg 1 -> eax, then ...
0010bc 89442404 (16) MOVL AX,4(SP) ; ... "pushed" onto stack
0010c0 b802000000 (16) MOVL $2,AX ; arg 2 -> eax, then ...
0010c5 89442408 (16) MOVL AX,8(SP) ; ... "pushed" onto stack
0010c9 b803000000 (16) MOVL $3,AX ; .
0010ce 8944240c (16) MOVL AX,12(SP) ; .
0010d2 b804000000 (16) MOVL $4,AX ; .
0010d7 89442410 (16) MOVL AX,16(SP) ; .
0010db 8d442414 (16) LEAL 20(SP),AX ; get ptr to next (unused) stack bytes -> eax ...
0010df 89442430 (16) MOVL AX,.safe+48(SP) ; ... and write it to very top of stack (seems aligned and not adjacent to last arg) | looks like callconv keeps a ptr to
0010e3 8b442430 (16) MOVL .safe+48(SP),AX ; regetting of same ptr into eax (pointless as same as in eax) | each struct params in local area
0010e7 c70005000000 (16) MOVL $5,(AX) ; |
0010ed 8b442430 (16) MOVL .safe+48(SP),AX ; |
0010f1 c7400406000000 (16) MOVL $6,4(AX) ; | copy struct linearly to stack, adjacent to other args
0010f8 8b442430 (16) MOVL .safe+48(SP),AX ; |
0010fc c7400807000000 (16) MOVL $7,8(AX) ; |
001103 c7400c00000000 (16) MOVL $0,12(AX) ; | msbytes of long long
00110a b808000000 (16) MOVL $8,AX ; arg 6 -> eax, then ...
00110f 89442424 (16) MOVL AX,36(SP) ; ... "pushed" onto stack
001113 b809000000 (16) MOVL $9,AX ; arg 7 -> eax, then ...
lib/Affix.pm view on Meta::CPAN
All the sugar is right here in the :Native code attribute. This API is inspired
by L<Raku's C<native> trait|https://docs.raku.org/language/nativecall>.
A simple example would look like this:
use Affix;
sub some_argless_function :Native('something');
some_argless_function();
The first line imports various code attributes and types. The next line looks
like a relatively ordinary Perl sub declaration--with a twist. We use the
C<:Native> attribute in order to specify that the sub is actually defined in a
native library. The platform-specific extension (e.g., .so or .dll), as well as
any customary prefixes (e.g., lib) will be added for you.
The first time you call "some_argless_function", the "libsomething" will be
loaded and the "some_argless_function" will be located in it. A call will then
be made. Subsequent calls will be faster, since the symbol handle is retained.
Of course, most functions take arguments or return values--but everything else
lib/Affix.pm view on Meta::CPAN
day => Int int day;
], } dob;
name => Str, char *name;
wId => Long long wId;
]; };
A struct consists of a sequence of members with storage allocated in an ordered
sequence (as opposed to C<Union>, which is a type consisting of a sequence of
members where storage overlaps).
A C struct that looks like this:
struct {
char *make;
char *model;
int year;
};
...would be defined this way:
Struct[
lib/Affix.pm view on Meta::CPAN
A union is a type consisting of a sequence of members with overlapping storage
(as opposed to C<Struct>, which is a type consisting of a sequence of members
whose storage is allocated in an ordered sequence).
The value of at most one of the members can be stored in a union at any one
time and the union is only as big as necessary to hold its largest member
(additional unnamed trailing padding may also be added). The other members are
allocated in the same bytes as part of that largest member.
A C union that looks like this:
union {
char c[5];
float f;
};
...would be defined this way:
Union[
c => ArrayRef[Char, 5],
lib/Affix.xs view on Meta::CPAN
#define GvNAMELEN_get GvNAMELEN
#endif
#ifndef CvGV_set
#define CvGV_set(cv, gv) (CvGV(cv) = (gv))
#endif
/* general utility */
#if PERL_BCDVERSION >= 0x5008005
#define LooksLikeNumber(x) looks_like_number(x)
#else
#define LooksLikeNumber(x) (SvPOKp(x) ? looks_like_number(x) : (I32)SvNIOKp(x))
#endif
// added in perl 5.35.7?
#ifndef sv_setbool_mg
#define sv_setbool_mg(sv, b) sv_setsv_mg(sv, boolSV(b))
#endif
#define newAV_mortal() (AV *)sv_2mortal((SV *)newAV())
#define newHV_mortal() (HV *)sv_2mortal((SV *)newHV())
#define newRV_inc_mortal(sv) sv_2mortal(newRV_inc(sv))
lib/Affix.xs view on Meta::CPAN
/* Int->sig == 'i'; Struct[Int, Float]->sig == '{if}' */ \
cv = newXSproto_portable(form("%s::sig", package), Types_sig, file, "$"); \
XSANY.any_i32 = (int)SIGCHAR; \
/* embed an extra character inside a method call to get the 'real' C type*/ \
cv = newXSproto_portable(form("%s::csig", package), Types_sig, file, "$"); \
XSANY.any_i32 = (int)SIGCHAR_C; \
/* types objects can stringify to sigchars */ \
cv = newXSproto_portable(form("%s::(\"\"", package), Types_sig, file, ";$"); \
XSANY.any_i32 = (int)SIGCHAR; \
/* The magic for overload gets a GV* via gv_fetchmeth as */ \
/* mentioned above, and looks in the SV* slot of it for */ \
/* the "fallback" status. */ \
sv_setsv(get_sv(form("%s::()", package), TRUE), &PL_sv_yes); \
/* Making a sub named "Affix::Call::Aggregate::()" allows the package */ \
/* to be findable via fetchmethod(), and causes */ \
/* overload::Overloaded("Affix::Call::Aggregate") to return true. */ \
(void)newXSproto_portable(form("%s::()", package), Types_sig, file, ";$"); \
}
#define CLEANUP(NAME) \
cv = get_cv(form("Affix::%s", #NAME), 0); \
( run in 0.426 second using v1.01-cache-2.11-cpan-64827b87656 )