chadjoan

An lm32 stack fixer

Aug 1st, 2020
2,303
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. auto fix_stack(alias funcSym, Args...)(Args args)
  2. {
  3.     template substitutePrimitives(size_t incomingArgIndex, OutgoingParamTypes...)
  4.     {
  5.         import std.conv : to;
  6.         import std.traits :
  7.             isPointer, isIntegral, isBuiltinType,
  8.             isDynamicArray, PointerTarget, Unqual;
  9.  
  10.         static if ( incomingArgIndex < args.length )
  11.         {
  12.             enum argForward = "args[" ~incomingArgIndex.to!string~ "]";
  13.             alias thisArg = args[incomingArgIndex];
  14.         }
  15.  
  16.         /+
  17.         static if ( true
  18.         && OutgoingParamTypes.length >= 2
  19.         && isDynamicArray!(typeof(args[incomingArgIndex]))
  20.         )
  21.         {
  22.             pragma(msg, "Found array at argument index " ~incomingArgIndex.to!string~ "\n"
  23.                 ~"Stats:\n"
  24.                 ~"  isPointer !(oparam[i+0])    == "~ isPointer !(OutgoingParamTypes[0]).to!string~ "\n"
  25.                 ~"  isIntegral!(oparam[i+1])    == "~ isIntegral!(OutgoingParamTypes[1]).to!string~ "\n"
  26.                 ~"  isBuiltinType!(oparam[i+1]) == "~ isBuiltinType!(OutgoingParamTypes[1]).to!string~ "\n"
  27.                 ~"  refered types equal?        == "~
  28.                     is( Unqual!(typeof(thisArg[0]))
  29.                     ==  Unqual!(PointerTarget!(OutgoingParamTypes[0])) ).to!string~ "\n"
  30.                 ~"  typeof(*oparam[i+0])        == "~ PointerTarget!(OutgoingParamTypes[0]).stringof~ "\n"
  31.                 ~"  typeof(iparam[i][0])        == "~ typeof(thisArg[0]).stringof~ "\n");
  32.         }
  33.         +/
  34.  
  35.         static if ( OutgoingParamTypes.length < 2 )
  36.         {
  37.             //pragma(msg, "OutgoingParamTypes.length < 2");
  38.             static if ( OutgoingParamTypes.length == 1 )
  39.                 enum substitutePrimitives = [argForward];
  40.             else
  41.                 enum substitutePrimitives = [];
  42.         }
  43.         else
  44.         static if ( true
  45.             // Match this situation:
  46.             // incoming:  T[]
  47.             // outgoing:  T*, size_t
  48.             && isPointer!(OutgoingParamTypes[0])
  49.             && isIntegral!(OutgoingParamTypes[1])
  50.             && isBuiltinType!(OutgoingParamTypes[1])
  51.             && isDynamicArray!(typeof(thisArg))
  52.             && is(
  53.                 Unqual!(typeof(thisArg[0]))
  54.                     == Unqual!(PointerTarget!(OutgoingParamTypes[0]))
  55.                 )
  56.         )
  57.         {
  58.             //pragma(msg, "array -> ptr+len");
  59.             enum substitutePrimitives =
  60.                 [argForward ~".ptr"] ~ [argForward ~".length"]
  61.                     ~ substitutePrimitives!(
  62.                         incomingArgIndex + 1, OutgoingParamTypes[2 .. $]);
  63.         }
  64.         else
  65.         {
  66.             //pragma(msg, "arg->param");
  67.             enum substitutePrimitives =
  68.                 [argForward]
  69.                     ~ substitutePrimitives!(
  70.                         incomingArgIndex + 1, OutgoingParamTypes[1 .. $]);
  71.         }
  72.     }
  73.  
  74.     import std.array : join;
  75.     import std.meta : AliasSeq;
  76.     import std.traits : Parameters;
  77.  
  78.     alias DstParamsTypes = Parameters!funcSym;
  79.     enum argString = substitutePrimitives!(0, DstParamsTypes).join(", ");
  80.     enum returnString = "return funcSym("~ argString ~");";
  81.     //pragma(msg, returnString);
  82.     mixin(returnString);
  83. }
  84.  
  85.  
  86. // C-like version, but with "const(char)*" instead of "const char*",
  87. // because pointers to string literals can be accepted by parameters
  88. // of type "const(char)*" but not "const(char*)".
  89. //
  90. // I also made `len` be a `ptrdiff_t` because it's a little closer
  91. // to being like what a .length property would return (e.g. inside
  92. // the automatically generated wrapper). But it might be very
  93. // nitpicky in this case and won't matter unless your code gets
  94. // ported to a processor where "int.sizeof != ptrdiff_t.sizeof".
  95. // And, of course, `size_t` would be *exactly* what .length would
  96. // return, but that's unsigned and I like to play it safe around
  97. // loops with decremented conditionals.
  98. //
  99. void write_to_hostC(const(char)* msg, ptrdiff_t len) {
  100.     char *ptr = cast(char*)msg;
  101.     char *usb_slave = cast(char*)BaseAdr.ft232_slave;
  102.     while (len--) {
  103.         *usb_slave = *ptr++;
  104.     }
  105. }
  106.  
  107. void call_a_stack_fixer()
  108. {
  109.     fix_stack!write_to_hostC("Hello world!\n");
  110. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×