home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 243,202 of 243,242   
   Waldek Hebisch to Bart   
   Re: printf and time_t   
   10 Feb 26 13:22:03   
   
   From: antispam@fricas.org   
      
   Bart  wrote:   
   > On 09/02/2026 01:27, Waldek Hebisch wrote:   
   >> Bart  wrote:   
   >>> On 08/02/2026 19:21, Waldek Hebisch wrote:   
   >>>> Bart  wrote:   
   >>>>> On 07/02/2026 22:48, Waldek Hebisch wrote:   
   >>>   
   >>>>> The last straw was precisely to do with the SYS V call-conventions, and   
   >>>>> I hadn't even gotten to variadic arguments yet, nor to structs passed   
   >>>>> by-value, where the rules are labyrinthine.   
   >>>>   
   >>>> My low-level code only handles scalar arguments.  That includes pointer   
   >>>> to structures, but not structures passed by value.  Structures passed by   
   >>>> value could be handled by higher-level code, but up to now there was   
   >>>> no need to do this.   
   >>>>   
   >>>> BTW, my amd64 code is assembler, so off-topic here, but arm32 code   
   >>>> is mostly C.  I use two helper structures:   
   >>>>   
   >>>> struct registers_buffer {   
   >>>>       int i_reg[4];   
   >>>>       union {double d; struct {float sl; float sh;} sf2;} f_reg[8];   
   >>>> };   
   >>>>   
   >>>> typedef struct registers_buffer reg_buff;   
   >>>>   
   >>>> typedef struct arg_state { int ni; int sfi; int dfi; int si;} arg_state;   
   >>>>   
   >>>> C code fills 'reg_buff' with values and later low-level assembly   
   >>>> copies values from the buffer to registers.  I allocate enough space on   
   >>>> the stack so that C code can write to the stack without risk of   
   >>>> stack overflow.   
   >>>>   
   >>>> There are 3 helper routines:   
   >>>   
   >>>   
   >>> This looks pretty complicated, but what is it for: is it still to do   
   >>> with variadic functions, or is to with the LIBFFI problem?   
   >>   
   >> This is to handle a call, it does not matter variadic or not.   
   >> The call is from dynamically typed language and argument types are   
   >> known only at runtime   
   >   
   > OK, so it is probably performing the LIBFFI thing, or rather what needs   
   > to come before, which is to marshall the arguments into homogenous array   
   > of values. The actual LIBFFI task needs some ASM support as you say.   
      
   As you can see from declaration of 'struct registers_buffer' values   
   are no homogeneous: there is separate part for integer registers   
   and separate part for floating point ones.  In arm32 pair of   
   single float registers overlaps with double float register,   
   that is why for floating point I use a union.   
      
   The C code is called from assembly code.  C code stores stack   
   arguments directly to the stack (before calling C code assembler   
   ensures that there is enough space on the stack for all arguments).   
   Since C code could use registers for its own purpose register   
   arguments are stored in a buffer and loaded after argument loop   
   is done.   
      
   > In that case, my own code to do the same (not in C) is probably more fiddly:   
   >   
   >   https://github.com/sal55/langs/blob/master/calldll.m   
   >   
   > The interpreter calls 'calldll()'. 'vartopacked()' does the translation   
   > from tagged dynamic values to suitable FFI types. Here the args are   
   > assembled into an i64 array.   
      
   It looks a bit simpler: AFAICS your code does not spread arguments   
   between various destinations (various kinds of registers and the stack).   
      
   > The actual call is done with 'os_calldllfunction' which uses inline   
   > assembly; that has been appended.   
   >   
   > I also have a version of that in pure HLL code, but it only handles the   
   > most common combinations. (I used that if transpiling to C.)   
   >   
   >   
   >> (actually, argument types _may_ be statically   
   >> known at higher level, but for simplicity "all" (see below) calls go   
   >> trough a single low-level routine that handles general dynamic case.   
   >> Dispatcher routine (which I did not show) loops over arguments,   
   >> decodes their types and converts them to C representation.  Then   
   >> it calls one of the 3 helper routines to place each argument in the buffer   
   >> or on the stack.   
   >>   
   >> There is simpler integer only code which is mainly used to perform   
   >> low level system calls.  This iterface do not convert arguments   
   >> (the assumption is that caller passes C-compatible representation)   
   >> and logic is simpler as it just puts what fits in registers and   
   >> the rest on the stack.   
   >>   
   >> Both interfaces spill all registers used by calling language to   
   >> the stack before actual processing of the call.  This is because   
   >> C code may perform a callback and callback may trigger garbage   
   >   
   > So here the dynamic code is not interpreted?   
      
   There are no interpreter: all code is compiled to machine code.  That   
   include user "command line".   
      
   But in principle adding a bytecode intepreter is not hard.  All   
   functions would need a small machine code stub to start interpreter.   
   There would be efficiency hit for calls to interpreted functions,   
   but probably not too bad (interpreted code is slow anyway).   
   ATM it is not clear to me if advantages (mainly smaller code)   
   justify needed effort.   
      
   > That's a problem for me: I can't pass a the address of a callback   
   > function which only exists as bytecode!   
   >   
   > (For the purpose of running WinAPI GUI programs, I set up a special   
   > callback function within the compiler, and that then has to start a new   
   > interpreter instance briefly.)   
      
   Yes, with simple enough interpreter one can start separate interpreter   
   "instance" for each call.   
      
   --   
                                 Waldek Hebisch   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca