Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- auto fix_stack(alias funcSym, Args...)(Args args)
- {
- template substitutePrimitives(size_t incomingArgIndex, OutgoingParamTypes...)
- {
- import std.conv : to;
- import std.traits :
- isPointer, isIntegral, isBuiltinType,
- isDynamicArray, PointerTarget, Unqual;
- static if ( incomingArgIndex < args.length )
- {
- enum argForward = "args[" ~incomingArgIndex.to!string~ "]";
- alias thisArg = args[incomingArgIndex];
- }
- /+
- static if ( true
- && OutgoingParamTypes.length >= 2
- && isDynamicArray!(typeof(args[incomingArgIndex]))
- )
- {
- pragma(msg, "Found array at argument index " ~incomingArgIndex.to!string~ "\n"
- ~"Stats:\n"
- ~" isPointer !(oparam[i+0]) == "~ isPointer !(OutgoingParamTypes[0]).to!string~ "\n"
- ~" isIntegral!(oparam[i+1]) == "~ isIntegral!(OutgoingParamTypes[1]).to!string~ "\n"
- ~" isBuiltinType!(oparam[i+1]) == "~ isBuiltinType!(OutgoingParamTypes[1]).to!string~ "\n"
- ~" refered types equal? == "~
- is( Unqual!(typeof(thisArg[0]))
- == Unqual!(PointerTarget!(OutgoingParamTypes[0])) ).to!string~ "\n"
- ~" typeof(*oparam[i+0]) == "~ PointerTarget!(OutgoingParamTypes[0]).stringof~ "\n"
- ~" typeof(iparam[i][0]) == "~ typeof(thisArg[0]).stringof~ "\n");
- }
- +/
- static if ( OutgoingParamTypes.length < 2 )
- {
- //pragma(msg, "OutgoingParamTypes.length < 2");
- static if ( OutgoingParamTypes.length == 1 )
- enum substitutePrimitives = [argForward];
- else
- enum substitutePrimitives = [];
- }
- else
- static if ( true
- // Match this situation:
- // incoming: T[]
- // outgoing: T*, size_t
- && isPointer!(OutgoingParamTypes[0])
- && isIntegral!(OutgoingParamTypes[1])
- && isBuiltinType!(OutgoingParamTypes[1])
- && isDynamicArray!(typeof(thisArg))
- && is(
- Unqual!(typeof(thisArg[0]))
- == Unqual!(PointerTarget!(OutgoingParamTypes[0]))
- )
- )
- {
- //pragma(msg, "array -> ptr+len");
- enum substitutePrimitives =
- [argForward ~".ptr"] ~ [argForward ~".length"]
- ~ substitutePrimitives!(
- incomingArgIndex + 1, OutgoingParamTypes[2 .. $]);
- }
- else
- {
- //pragma(msg, "arg->param");
- enum substitutePrimitives =
- [argForward]
- ~ substitutePrimitives!(
- incomingArgIndex + 1, OutgoingParamTypes[1 .. $]);
- }
- }
- import std.array : join;
- import std.meta : AliasSeq;
- import std.traits : Parameters;
- alias DstParamsTypes = Parameters!funcSym;
- enum argString = substitutePrimitives!(0, DstParamsTypes).join(", ");
- enum returnString = "return funcSym("~ argString ~");";
- //pragma(msg, returnString);
- mixin(returnString);
- }
- // C-like version, but with "const(char)*" instead of "const char*",
- // because pointers to string literals can be accepted by parameters
- // of type "const(char)*" but not "const(char*)".
- //
- // I also made `len` be a `ptrdiff_t` because it's a little closer
- // to being like what a .length property would return (e.g. inside
- // the automatically generated wrapper). But it might be very
- // nitpicky in this case and won't matter unless your code gets
- // ported to a processor where "int.sizeof != ptrdiff_t.sizeof".
- // And, of course, `size_t` would be *exactly* what .length would
- // return, but that's unsigned and I like to play it safe around
- // loops with decremented conditionals.
- //
- void write_to_hostC(const(char)* msg, ptrdiff_t len) {
- char *ptr = cast(char*)msg;
- char *usb_slave = cast(char*)BaseAdr.ft232_slave;
- while (len--) {
- *usb_slave = *ptr++;
- }
- }
- void call_a_stack_fixer()
- {
- fix_stack!write_to_hostC("Hello world!\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement