The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Dyn::Call - Architecture-, OS- and Compiler-agnostic Function Call Semantics

SYNOPSIS

    use Dyn::Call qw[:all];
    # ...
    my $cvm = dcNewCallVM( 1024 );
    dcMode( $cvm, 0 );
    dcReset( $cvm );
    dcArgInt( $cvm, 5 );
    dcArgInt( $cvm, 6 );
    dcCallInt( $cvm, $ptr ); #  '5 + 6 == 11';

DESCRIPTION

Dyn::Call wraps the dyncall CallVM; a state machine which provides low-level functionality to make foreign function calls from different run-time environments. The flexibility is constrained by the set of supported types.

Everything listed here may be imported by name, with the given import tag or with the :all tag.

Call Virtual Machine (CallVM) Functions

These functions effect the CallVM which manages all aspects of a function call from configuration, argument passing up the actual function call on the processor.

You may import functions here by name or with the :callvm tag.

dcNewCallVM( ... )

    my $cvm = dcNewCallVM( 1024 );

This function creates a new CallVM object, where size specifies the max size of the internal stack that will be allocated and used to bind arguments to. You must use dcFree( ... ) to properly destroy the CallVM object.

Expected parameters include:

size - stack size

Returns a new CallVM object on success.

dcFree( ... )

Destroy a CallVM instance.

    dcFree( $cvm );

Expected parameters include:

vm - Dyn::Call object

dcGetError( ... )

Returns the most recent error state code.

    my $error = dcGetError( $cvm );

Expected parameters include:

vm - Dyn::Call object

Possible error states are listed below.

dcMode( ... )

Sets the calling convention to use.

    dcMode( $cvm, DC_CALL_C_DEFAULT );

Note that some mode/platform combinations don't make any sense (e.g. using a PowerPC calling convention on a MIPS platform) and are silently ignored.

Expected parameters include:

vm - Dyn::Call object
mode - See list of possible modes below

DC_CALL_C_DEFAULT is the default standard C call on the target platform. It uses the standard C calling convention. DC_CALL_C_ELLIPSIS is used for C ellipsis calls which allow to build up a variable argument list. On many platforms, there is only one C calling convention. The X86 platform provides a rich family of different calling conventions.

dcReset( ... )

Resets the internal stack of arguments and prepares it for a new call.

This function should be called after setting the call mode (using dcMode( ... )), but prior to binding arguments to the Dyn::Call VM (except for when setting mode DC_SIGCHAR_CC_ELLIPSIS_VARARGS, which is used prior to binding varargs of variadic functions). Use it also when reusing a Dyn::Call VM, as arguments don't get flushed automatically after a function call invocation.

Expected parameters include:

vm - Dyn::Call object

Note: you should also call this function after initial creation of the a Dyn::Call object, as dcNewCallVM( ... ) doesn't do this, implicitly.

Argument Binding Functions

These functions are used to bind arguments of the named types to the CallVM object. Arguments should be bound in left-to-right order regarding the C style function prototype.

These functions may be imported by name or with the :bind tag.

dcArgBool( ... )

Pushes a boolean value onto the argument stack.

    dcArgBool( $cvm, 1 ); # or 0, of course

Expected parameters include:

vm - Dyn::Call object
arg - a boolean value

dcArgChar( ... )

Pushes a char value onto the argument stack.

    dcArgChar( $cvm, 'a' );

Expected parameters include:

vm - Dyn::Call object
arg - a char value

dcArgShort( ... )

Pushes a short integer value onto the argument stack.

    dcArgShort( $cvm, -500 );

Expected parameters include:

vm - Dyn::Call object
arg - a short value

dcArgInt( ... )

Pushes an integer value onto the argument stack.

    dcArgInt( $cvm, -500 );

Expected parameters include:

vm - Dyn::Call object
arg - an integer value

dcArgLong( ... )

Pushes a long integer value onto the argument stack.

    dcArgLong( $cvm, -2147483647 );

Expected parameters include:

vm - Dyn::Call object
arg - an long integer value

dcArgLongLong( ... )

Pushes a long long integer value onto the argument stack.

    dcArgLongLong( $cvm, -9223372036854775807 );

Expected parameters include:

vm - Dyn::Call object
arg - an long long integer value

dcArgFloat( ... )

Pushes a single-precision floating point value onto the argument stack.

    dcArgFloat( $cvm, 3.14 );

Expected parameters include:

vm - Dyn::Call object
arg - a floating point value

dcArgDouble( ... )

Pushes a double-precision floating point value onto the argument stack.

    dcArgDouble( $cvm, 3.14 );

Expected parameters include:

vm - Dyn::Call object
arg - a floating point value

dcArgPointer( ... )

Pushes a pointer (void *) value onto the argument stack.

    dcArgPointer( $cvm, $struct );

Expected parameters include:

vm - Dyn::Call object
arg - a pointer

dcArgString( ... )

Pushes a string (char *) value onto the argument stack.

    dcArgString( $cvm, 'John' );

Expected parameters include:

vm - Dyn::Call object
arg - a string

Call Invocation Functions

These functions call the function specified by funcptr with the arguments bound to the CallVM and returns. Use the function that corresponds to the dynamically called function's return value.

After the invocation of the foreign function call, the argument values are still bound and a second call using the same arguments can be issued. If you need to clear the argument bindings, you have to reset the CallVM.

These functions may be imported by name or with the :call tag.

dcCallVoid( ... )

Invokes the function with a the expectations of void return value.

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallBool( ... )

Invokes the function with the expectations of a boolean return value.

    my $tf = dcCallBool( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallChar( ... )

Invokes the function with the expectations of a char return value.

    my $char = dcCallChar( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallShort( ... )

Invokes the function with the expectations of a short return value.

    my $ret = dcCallShort( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallInt( ... )

Invokes the function with the expectations of a integer return value.

    my $sum = dcCallInt( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallLong( ... )

Invokes the function with the expectations of a long return value.

    my $val1 = dcCallLong( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallLongLong( ... )

Invokes the function with the expectations of a long long return value.

    my $val2 = dcCallLongLong( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallFloat( ... )

Invokes the function with the expectations of a float return value.

    my $f = dcCallFloat( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallDouble( ... )

Invokes the function with the expectations of a double return value.

    my $num = dcCallDouble( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallPointer( ... )

Invokes the function with a the expectations of a pointer (void *) return value.

    my $ptr = dcCallPointer( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

dcCallString( ... )

Invokes the function with a string (const char *) return value.

    my $str = dcCallString( $cvm, $funcptr );

Expected parameters include:

vm - Dyn::Call object
funcptr - function pointer

Structure Functions

These functions aide in computing the size of a structure. They may be imported by name or with the :struct tag.

dcNewStruct( ... )

Creates a new DCstruct.

    my $struct = dcNewStruct( 4, DEFAULT_ALIGNMENT );

Expected parameters include:

fieldCount - the number of fields in the structure
alignment - data structure alignment

dcStructField( ... )

Adds a new field to the structure.

    dcStructField( $struct, DC_SIGCHAR_INT, DEFAULT_ALIGNMENT, 1 );

Expected parameters include:

struct - DCstruct
type - Structure type (you may reuse signature values here)
alignment - data structure alignment
arrayLength - number of elements in field

dcSubStruct( ... )

Nests a structure inside of another.

    dcSubStruct( $struct, 1, DEFAULT_ALIGNMENT, 1 );

Expected parameters include:

struct - DCstruct
fieldCount - the number of fields in the structure
alignment - data structure alignment
arrayLength - number of elements in field

Errors

These values are returned by dcGetError( ... ) and include:

DC_ERROR_NONE - No error occurred
DC_ERROR_UNSUPPORTED_MODE - Unsupported mode; caused by dcMode( ... )

Modes

You may set the calling convention to use with dcMode( ... ).

DC_CALL_C_DEFAULT - C default function call for current platform
DC_CALL_C_ELLIPSIS - C ellipsis function call (named arguments (before '...'))
DC_CALL_C_ELLIPSIS_VARARGS - C ellipsis function call (variable/unnamed arguments (after '...'))
DC_CALL_C_X86_CDECL - C x86 platforms standard call
DC_CALL_C_X86_WIN32_STD - C x86 Windows standard call
DC_CALL_C_X86_WIN32_FAST_MS - C x86 Windows Microsoft fast call
DC_CALL_C_X86_WIN32_FAST_GNU - C x86 Windows GCC fast call
DC_CALL_C_X86_WIN32_THIS_MS - C x86 Windows Microsoft this call
DC_CALL_C_X86_WIN32_THIS_GNU - alias for DC_CALL_C_X86_CDECL (GNU this call is identical to cdecl)
DC_CALL_C_X86_PLAN9 - C x86 Plan9 call
DC_CALL_C_X64_WIN64 - C x64 Windows standard call
DC_CALL_C_X64_SYSV - C x64 System V standard call
DC_CALL_C_PPC32_DARWIN - C ppc32 Mac OS X standard call
DC_CALL_C_PPC32_OSX - alias for DC_CALL_C_PPC32_DARWIN
DC_CALL_C_PPC32_SYSV - C ppc32 SystemV standard call
DC_CALL_C_PPC32_LINUX - alias for DC_CALL_C_PPC32_SYSV
DC_CALL_C_PPC64 - C ppc64 SystemV standard call
DC_CALL_C_PPC64_LINUX - alias for DC_CALL_C_PPC64
DC_CALL_C_ARM_ARM - C arm call (arm mode)
DC_CALL_C_ARM_THUMB - C arm call (thumb mode)
DC_CALL_C_ARM_ARM_EABI - C arm eabi call (arm mode)
DC_CALL_C_ARM_THUMB_EABI - C arm eabi call (thumb mode)
DC_CALL_C_ARM_ARMHF - C arm call (arm hardfloat - e.g. raspberry pi)
DC_CALL_C_ARM64 - C arm64 call (AArch64)
DC_CALL_C_MIPS32_EABI - C mips32 eabi call
DC_CALL_C_MIPS32_PSPSDK - alias for DC_CALL_C_MIPS32_EABI (deprecated)
DC_CALL_C_MIPS32_O32 - C mips32 o32 call
DC_CALL_C_MIPS64_N64 - C mips64 n64 call
DC_CALL_C_MIPS64_N32 - C mips64 n32 call
DC_CALL_C_SPARC32 - C sparc32 call
DC_CALL_C_SPARC64 - C sparc64 call
DC_CALL_SYS_DEFAULT - C default syscall for current platform
DC_CALL_SYS_X86_INT80H_BSD - C syscall for x86 BSD platforms
DC_CALL_SYS_X86_INT80H_LINUX - C syscall for x86 Linux
DC_CALL_SYS_X64_SYSCALL_SYSV - C syscall for x64 System V platforms
DC_CALL_SYS_PPC32 - C syscall for ppc32
DC_CALL_SYS_PPC64 - C syscall for ppc64

Signature

DC_SIGCHAR_VOID
DC_SIGCHAR_BOOL
DC_SIGCHAR_CHAR
DC_SIGCHAR_UCHAR
DC_SIGCHAR_SHORT
DC_SIGCHAR_USHORT
DC_SIGCHAR_INT
DC_SIGCHAR_UINT
DC_SIGCHAR_LONG
DC_SIGCHAR_ULONG
DC_SIGCHAR_LONGLONG
DC_SIGCHAR_ULONGLONG
DC_SIGCHAR_FLOAT
DC_SIGCHAR_DOUBLE
DC_SIGCHAR_POINTER
DC_SIGCHAR_STRING - in theory same as DC_SIGCHAR_POINTER, but convenient to disambiguate
DC_SIGCHAR_STRUCT
DC_SIGCHAR_ENDARG - also works for end struct

Calling Convention / Mode Signatures

DC_SIGCHAR_CC_PREFIX
DC_SIGCHAR_CC_DEFAULT
DC_SIGCHAR_CC_ELLIPSIS
DC_SIGCHAR_CC_ELLIPSIS_VARARGS
DC_SIGCHAR_CC_CDECL
DC_SIGCHAR_CC_STDCALL
DC_SIGCHAR_CC_FASTCALL_MS
DC_SIGCHAR_CC_FASTCALL_GNU
DC_SIGCHAR_CC_THISCALL_MS
DC_SIGCHAR_CC_THISCALL_GNU - GNU thiscalls are cdecl, but keep specific sig char for clarity
DC_SIGCHAR_CC_ARM_ARM
DC_SIGCHAR_CC_ARM_THUMB
DC_SIGCHAR_CC_SYSCALL

Structures

DEFAULT_ALIGNMENT - Default value for data structure alignment

Memory Functions

See Dyn::Call::Pointer for a list of direct memory manipulation functions which may be imported with the :memory tag.

Platform Support

The dyncall library runs on many different platforms and operating systems (including Windows, Linux, OpenBSD, FreeBSD, macOS, DragonFlyBSD, NetBSD, Plan9, iOS, Haiku, Nintendo DS, Playstation Portable, Solaris, Minix, Raspberry Pi, ReactOS, etc.) and processors (x86, x64, arm (arm & thumb mode), arm64, mips, mips64, ppc32, ppc64, sparc, sparc64, etc.).

LICENSE

Copyright (C) Sanko Robinson.

This library is free software; you can redistribute it and/or modify it under the terms found in the Artistic License 2. Other copyrights, terms, and conditions may apply to data transmitted through this module.

AUTHOR

Sanko Robinson <sanko@cpan.org>