Stack
  cr()




                                      cr
                                  (_alloca)


                   EBP2             EBP1
                                    main+x
                   EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)




                     caller

                                          cr
                                      (_alloca)


                       EBP2             EBP1
                                        main+x
                       EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)
         exec()




                       EBP3             EBP2
                                        cr+x
                     caller

                                          cr
                                      (_alloca)


                       EBP2             EBP1
                                        main+x
                       EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)
         exec()                                test
                   test()                      ???+x
                                                ???
                                               EBP3
                                              exec+x
                                               exec
                              EBP3             EBP2
                                               cr+x
                            caller

                                                 cr
                                             (_alloca)


                              EBP2             EBP1
                                               main+x
                              EBP1             main
… Return address
Stack
  cr()                                                yield
    setjmp(caller)                                   test+x
         exec()                                       test
                   test()                             ???+x
                        yield(0)                       ???
                                                      EBP3
                                                     exec+x
                                                      exec
                                     EBP3             EBP2
                                                      cr+x
                                   caller

                                                        cr
                                                    (_alloca)


                                     EBP2             EBP1
                                                      main+x
                                     EBP1             main
… Return address
Stack
  cr()                                       callee             yield
    setjmp(caller)                                             test+x
         exec()                                                 test
                   test()                                       ???+x
                        yield(0)                                 ???
                            setjmp(callee)                      EBP3
                                                               exec+x
                                                                exec
                                               EBP3             EBP2
                                                                cr+x
                                             caller

                                                                  cr
                                                              (_alloca)


                                               EBP2             EBP1
                                                                main+x
                                               EBP1             main
… Return address
Saved.
                                                       Stack
  cr()                                        callee             yield
    setjmp(caller)                                              test+x
         exec()                                                  test
                   test()                                        ???+x
                        yield(0)                                  ???
                            setjmp(callee)                       EBP3
                            longjmp(caller)                     exec+x
                                                                 exec
                                                EBP3             EBP2
                                                                 cr+x
                                              caller

                                                                   cr
                                                               (_alloca)


                                                EBP2             EBP1
                                                                 main+x
                                                EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)




                     caller

                                          cr
                                      (_alloca)


                       EBP2             EBP1
                                        main+x
                       EBP1             main
… Return address
Return to main
                                           Stack




                                    EBP1           main
… Return address
Stack




test2()




                   EBP2           EBP1
                                  main+x
                   EBP1           main
… Return address
Stack




test2()
          cr()




                   EBP3’             EBP2
                                    test2+x
                     EBP2            EBP1
                                    main+x
                     EBP1            main
… Return address
Stack




test2()
          cr()
           setjmp(caller)


                            caller

                            EBP3’             EBP2
                                             test2+x
                              EBP2            EBP1
                                             main+x
                              EBP1            main
… Return address
Stack




test2()
          cr()
           setjmp(caller)
           longjmp(callee)
                             caller

                             EBP3’             EBP2
                                              test2+x
                               EBP2            EBP1
                                              main+x
                               EBP1            main
… Return address
Restored.
                                                       Stack
  cr()                                        callee            yield
    setjmp(caller)                                             test+x
         exec()                                                 test
                   test()                                       ???+x
                        yield(0)                                 ???
                             setjmp(callee)                     EBP3
                                                               exec+x
                                                                exec
                                                EBP3            EBP2
                                                                cr+x

                                                               _alloca
                                              caller

                                              EBP3’             EBP2
                                                               test2+x
                                                EBP2            EBP1
                                                               main+x
                                                EBP1            main
… Return address
Stack
  cr()                               callee

    setjmp(caller)
         exec()                                        test
                   test()                              ???+x
                            Return                      ???
                                                       EBP3
                                                      exec+x
                                                       exec
                                       EBP3            EBP2
                                                       cr+x

                                                      _alloca
                                     caller

                                     EBP3’             EBP2
                                                      test2+x
                                       EBP2            EBP1
                                                      main+x
                                       EBP1            main
… Return address
Stack
  cr()                       callee

    setjmp(caller)
         exec()
                   test()
           longjmp(caller)



                                               exec
                               EBP3            EBP2
                                               cr+x

                                              _alloca
                             caller

                             EBP3’             EBP2
                                              test2+x
                               EBP2            EBP1
                                              main+x
                               EBP1            main
… Return address
Stack
                            callee




test2()
          cr()
           setjmp(caller)


                            caller

                            EBP3’             EBP2
                                             test2+x
                              EBP2            EBP1
                                             main+x
                              EBP1            main
… Return address
Stack
                            callee




test2()
                   Return



                            caller




                              EBP2           EBP1
                                             main+x
                              EBP1           main
… Return address
WHAT IF WE DON’T USE THE `EXEC’
WRAPPER?
Stack
  cr()




                                      cr
                                  (_alloca)


                   EBP2             EBP1
                                    main+x
                   EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)




                     caller

                                          cr
                                      (_alloca)


                       EBP2             EBP1
                                        main+x
                       EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)
         test()



                                        test
                                        ???+x
                                         ???
                                        EBP2
                                         cr+x
                     caller

                                          cr
                                      (_alloca)


                       EBP2             EBP1
                                        main+x
                       EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)
         test()
               yield(0)             callee             yield
                   setjmp(callee)                     test+x
                                                       test
                                                       ???+x
                                                        ???
                                                       EBP2
                                                        cr+x
                                    caller

                                                         cr
                                                     (_alloca)


                                      EBP2             EBP1
                                                       main+x
                                      EBP1             main
… Return address
Saved.     Stack
  cr()
    setjmp(caller)
         test()
               yield(0)                callee             yield
                   setjmp(callee)                        test+x
                   longjmp(caller)                        test
                                                          ???+x
                                                           ???
                                                          EBP2
                                                           cr+x
                                       caller

                                                            cr
                                                        (_alloca)


                                         EBP2             EBP1
                                                          main+x
                                         EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)




                     caller

                                          cr
                                      (_alloca)


                       EBP2             EBP1
                                        main+x
                       EBP1             main
… Return address
Return to main
                                           Stack




                                    EBP1           main
… Return address
Stack




test2()




                   EBP2           EBP1
                                  main+x
                   EBP1           main
… Return address
Stack




test2()
          cr()




                   EBP3’             EBP2
                                    test2+x
                     EBP2            EBP1
                                    main+x
                     EBP1            main
… Return address
Stack




test2()
          cr()
           setjmp(caller)


                            caller

                            EBP3’             EBP2
                                             test2+x
                              EBP2            EBP1
                                             main+x
                              EBP1            main
… Return address
Stack




test2()
          cr()
           setjmp(caller)
           longjmp(callee)
                             caller

                             EBP3’             EBP2
                                              test2+x
                               EBP2            EBP1
                                              main+x
                               EBP1            main
… Return address
Restored.    Stack
  cr()
    setjmp(caller)
         test()
               yield(0)                  callee             yield
                   setjmp(callee)                          test+x
                   longjmp(caller)                          test
                                                            ???+x
                                                             ???
                                                            EBP2
                                                             cr+x
                                                              cr
                                         caller           (_alloca)
                                         EBP3’              EBP2
                                                           test2+x
                                           EBP2             EBP1
                                                            main+x
                                           EBP1             main
… Return address
Stack
  cr()
    setjmp(caller)
         test()
                     Return   callee



                                                 test
                                                 ???+x
                                                  ???
                                                 EBP2
                                                  cr+x
                                                   cr
                              caller           (_alloca)
                              EBP3’              EBP2
                                                test2+x
                                EBP2             EBP1
                                                 main+x
                                EBP1             main
… Return address
Stack
  cr()
                   Return

                                    callee




                                                           EBP2


                                                             cr
                                     caller              (_alloca)
                                    EBP3’                  EBP2
                            Current EBP                   test2+x
                                          EBP2             EBP1
                                                           main+x
                                          EBP1             main
… Return address
Stack
     cr()



                              callee




                                                     EBP2

EBP points to the
    wrong place.                                       cr
         ->                    caller              (_alloca)
  Access to local             EBP3’                  EBP2
 variables fails.
                      Current EBP                   test2+x
                                    EBP2             EBP1
                                                     main+x
                                    EBP1             main
   … Return address

Coroutine

  • 1.
    Stack cr() cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 2.
    Stack cr() setjmp(caller) caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 3.
    Stack cr() setjmp(caller) exec() EBP3 EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 4.
    Stack cr() setjmp(caller) exec() test test() ???+x ??? EBP3 exec+x exec EBP3 EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 5.
    Stack cr() yield setjmp(caller) test+x exec() test test() ???+x yield(0) ??? EBP3 exec+x exec EBP3 EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 6.
    Stack cr() callee yield setjmp(caller) test+x exec() test test() ???+x yield(0) ??? setjmp(callee) EBP3 exec+x exec EBP3 EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 7.
    Saved. Stack cr() callee yield setjmp(caller) test+x exec() test test() ???+x yield(0) ??? setjmp(callee) EBP3 longjmp(caller) exec+x exec EBP3 EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 8.
    Stack cr() setjmp(caller) caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 9.
    Return to main Stack EBP1 main … Return address
  • 10.
    Stack test2() EBP2 EBP1 main+x EBP1 main … Return address
  • 11.
    Stack test2() cr() EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 12.
    Stack test2() cr() setjmp(caller) caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 13.
    Stack test2() cr() setjmp(caller) longjmp(callee) caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 14.
    Restored. Stack cr() callee yield setjmp(caller) test+x exec() test test() ???+x yield(0) ??? setjmp(callee) EBP3 exec+x exec EBP3 EBP2 cr+x _alloca caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 15.
    Stack cr() callee setjmp(caller) exec() test test() ???+x Return ??? EBP3 exec+x exec EBP3 EBP2 cr+x _alloca caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 16.
    Stack cr() callee setjmp(caller) exec() test() longjmp(caller) exec EBP3 EBP2 cr+x _alloca caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 17.
    Stack callee test2() cr() setjmp(caller) caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 18.
    Stack callee test2() Return caller EBP2 EBP1 main+x EBP1 main … Return address
  • 19.
    WHAT IF WEDON’T USE THE `EXEC’ WRAPPER?
  • 20.
    Stack cr() cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 21.
    Stack cr() setjmp(caller) caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 22.
    Stack cr() setjmp(caller) test() test ???+x ??? EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 23.
    Stack cr() setjmp(caller) test() yield(0) callee yield setjmp(callee) test+x test ???+x ??? EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 24.
    Saved. Stack cr() setjmp(caller) test() yield(0) callee yield setjmp(callee) test+x longjmp(caller) test ???+x ??? EBP2 cr+x caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 25.
    Stack cr() setjmp(caller) caller cr (_alloca) EBP2 EBP1 main+x EBP1 main … Return address
  • 26.
    Return to main Stack EBP1 main … Return address
  • 27.
    Stack test2() EBP2 EBP1 main+x EBP1 main … Return address
  • 28.
    Stack test2() cr() EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 29.
    Stack test2() cr() setjmp(caller) caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 30.
    Stack test2() cr() setjmp(caller) longjmp(callee) caller EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 31.
    Restored. Stack cr() setjmp(caller) test() yield(0) callee yield setjmp(callee) test+x longjmp(caller) test ???+x ??? EBP2 cr+x cr caller (_alloca) EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 32.
    Stack cr() setjmp(caller) test() Return callee test ???+x ??? EBP2 cr+x cr caller (_alloca) EBP3’ EBP2 test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 33.
    Stack cr() Return callee EBP2 cr caller (_alloca) EBP3’ EBP2 Current EBP test2+x EBP2 EBP1 main+x EBP1 main … Return address
  • 34.
    Stack cr() callee EBP2 EBP points to the wrong place. cr -> caller (_alloca) Access to local EBP3’ EBP2 variables fails. Current EBP test2+x EBP2 EBP1 main+x EBP1 main … Return address