home bbs files messages ]

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

   comp.arch      Apparently more than just beeps & boops      131,241 messages   

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

   Message 130,248 of 131,241   
   EricP to Niklas Holsti   
   Re: branch splitting (1/2)   
   11 Nov 25 14:23:38   
   
   From: ThatWouldBeTelling@thevillage.com   
      
   Niklas Holsti wrote:   
   > On 2025-11-06 20:28, MitchAlsup wrote:   
   >>   
   >> Niklas Holsti  posted:   
   >>   
   >>> On 2025-11-05 23:28, MitchAlsup wrote:   
   >>>>   
   >>>> Niklas Holsti  posted:   
   >>> ----------------   
   >>>>> But then you could get the problem of a longjmp to a setjmp value that   
   >>>>> is stale because the targeted function invocation (stack frame) is no   
   >>>>> longer there.   
   >>>>   
   >>>> But YOU had to pass the jumpbuf out of the setjump() scope.   
   >>>>   
   >>>> Now, YOU complain there is a hole in your own foot with a smoking gun   
   >>>> in your own hand.   
   >>>   
   >>> That is not the issue. The question is if the semantics of "goto   
   >>> label-valued-variable" are hard to define, as Ritchie said, or not, as   
   >>> Anton thinks Stallman said or would have said.   
   >>   
   >> So, label-variables are hard to define, but function-variables are not   
   >> ?!?   
   >   
   > Depends on the level at which you want to define it.   
   >   
   > At the machine level, where semantics are (usually) defined for each   
   > instruction separately, a jump to a dynamic address (using a   
   > "label-variable") is not much different from a call to a dynamic address   
   > (using a "function-variable"), and the effect of the single instruction   
   > on the machine state is much the same as for the static address case.   
   > The higher-level effect on the further execution of the program is out   
   > of scope, whatever the actual value of the target address in the   
   > instruction.   
   >   
   > It is only if your machine has some semantics for instruction   
   > combinations, such as your VEC-LOOP pair, that you have to define what   
   > happens if a jump or call to some address leads to later executing only   
   > some of those instructions or executing them in the wrong order, such as   
   > trying to execute a LOOP without having executed a preceding VEC.   
   >   
   > At the higher programming-language level, the label case can be much   
   > harder to define and less useful than the function case, depending on   
   > the programming language and its abstract model of execution, and also   
   > depending on what compile-time checks you assume.   
   >   
   > Consider an imperative language such as C with no functions nested   
   > within other functions or other blocks (where by "block" I mean some   
   > syntactical construct that sets up its local context with local   
   > variables etc.). If you have a function-variable (that is, a pointer to   
   > a function) that actually refers to a function with the same parameter   
   > profile, it is easy to define the semantics of a call via this function   
   > variable: it is the same as for a call that names the referenced   
   > function statically, and such a call is always legal. Problems arise   
   > only if the function-variable has some invalid value such as NULL, or   
   > the address of a function with a different profile, or some code address   
   > that does not refer to (the start of) a function. Such invalid values   
   > can be prevented at compile time, except (usually) for NULL.   
   >   
   > In the same language setting, the semantics of a jump using a   
   > label-variable are easy to define only if the label-variable refers to a   
   > label in the same block as the jump. A jump from one block into another   
   > would mess up the context, omitting the set-up of the target block's   
   > context and/or omitting the tear-down of the source block's context. The   
   > further results of program execution are machine-dependent and so   
   > undefined behavior.   
   >   
   > A compiler could enforce the label-in-same-block rule, but it seems that   
   > GNU C does not do so.   
   >   
   > In a programming language that allows nested functions the same kind of   
   > context-crossing problems arise for function-variables. Traditional   
   > languages solve them by allowing, at compile-time, calls via   
   > function-variables only if it is certain that the containing context of   
   > the callee still exists (if the callee is nested), or by (expensively)   
   > preserving that context as a dynamically constructed closure. In either   
   > case, the caller's context never needs to be torn down to execute the   
   > call, differing from the jump case.   
   >   
   > In summary, jumps via label-variables are useful only for control   
   > transfers within one function, and do not help to build up a computation   
   > by combining several functions -- the main method of program design at   
   > present. In contrast, calls via function-variables are a useful   
   > extension to static calls, actually helping to combine several functions   
   > in a computation, as shown by the general adoption of   
   > class/object/method coding styles.   
   >   
   > Niklas   
   >   
      
   I was curious about the interaction between dynamic stack allocations   
   and goto variables to see if it handled the block scoping correctly.   
   Ada should have the same issues as C.   
   It appears GCC x86-64 15.2 with -O3 does not properly recover   
   stack space with dynamic goto's.   
      
   Test1 allocates a dynamic sized buffer and has a static goto Loop   
   for which GCC generates a jne .L6 to a mov rsp, rbx that recovers   
   the stack allocation inside the {} block.   
      
   Test2 is the same but does a goto *dest and GCC does not generate   
   code to recover the inner {} block allocation. It just loops over   
   the sub rsp, rbx so the stack space just grows.   
      
   long Sub (long len, char buf[]);   
      
   void Test1 (long len)   
   {   
      long ok;   
      
      Loop:   
      {   
        char buf[len];   
      
        ok = Sub (len, buf);   
        if (ok)   
          goto Loop;   
      }   
   }   
      
   # Compilation provided by Compiler Explorer at https://godbolt.org/   
   Test1(long):   
            push    rbp   
            mov     rbp, rsp   
            push    r13   
            mov     r13, rdi   
            push    r12   
            lea     r12, [rdi+15]   
            push    rbx   
            shr     r12, 4   
            sal     r12, 4   
            sub     rsp, 8   
            jmp     .L2   
   .L6:   
            mov     rsp, rbx   
   .L2:   
            mov     rbx, rsp   
            sub     rsp, r12   
            mov     rdi, r13   
            mov     rsi, rsp   
            call    Sub(long, char*)   
            test    rax, rax   
            jne     .L6   
            lea     rsp, [rbp-24]   
            pop     rbx   
            pop     r12   
            pop     r13   
            pop     rbp   
            ret   
      
   void Test2 (long len)   
   {   
      long ok;   
      void *dest;   
      
      dest = &&Loop;   
      Loop:   
      {   
        char buf[len];   
      
        ok = Sub (len, buf);   
        if (ok)   
          goto *dest;   
      }   
   }   
      
   Test2(long):   
            push    rbp   
            mov     rbp, rsp   
            push    r12   
            mov     r12, rdi   
            push    rbx   
            lea     rbx, [rdi+15]   
            shr     rbx, 4   
            sal     rbx, 4   
   .L8:   
            sub     rsp, rbx   
            mov     rdi, r12   
            mov     rsi, rsp   
            call    Sub(long, char*)   
            test    rax, rax   
            jne     .L8   
            lea     rsp, [rbp-16]   
            pop     rbx   
            pop     r12   
            pop     rbp   
            ret   
      
   --- 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