← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] cherry-picks related with sheet to stable branch 4.0

 

Le 29/05/2017 à 19:07, Eldar Khayrullin a écrit :
> /home/eldar/src/kicad/kicad/include/tool/coroutine.h:30:38: fatal error: boost/context/fcontext.hpp:
> file haven't found
>  #include <boost/context/fcontext.hpp>
> 
> I use -DKICAD_SKIP_BOOST=ON
> 
> В Понедельник, 29 май. 2017 в 7:33 , jp charras <jp.charras@xxxxxxxxxx> написал:
>> Le 29/05/2017 à 17:57, Eldar Khayrullin a écrit :
>>
>>     Sorry Jean-Pier, I didn't try to build it because I can't to build stable branch on my system
>>     (some library conflicting). 
>>
>> Well, what is your problem? If it is related to a boost context version, I have a patch to fix it.
>> -- 
>> Jean-Pierre CHARRAS 


OK, this is the boost context issue.
Apply this patch, and try to compile the stable version.

We are reluctant to apply this change to the stable version because it needs a c++11 compiler
(stable version does need it).

-- 
Jean-Pierre CHARRAS
 CMakeLists.txt               |   2 +-
 common/CMakeLists.txt        |   2 +
 common/system/libcontext.cpp | 712 +++++++++++++++++++++++++++++++++++++++++++
 common/tool/tool_manager.cpp |   2 +-
 include/system/libcontext.h  |  96 ++++++
 include/tool/coroutine.h     | 323 +++++++++++++-------
 6 files changed, 1033 insertions(+), 104 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 09932cc..30d284a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -584,7 +584,7 @@ endif()
 # Download boost and possibly build parts of it
 #################################################
 if( KICAD_SKIP_BOOST )
-    find_package( Boost 1.54.0 REQUIRED COMPONENTS context date_time filesystem iostreams locale
+    find_package( Boost 1.54.0 REQUIRED COMPONENTS date_time filesystem iostreams locale
                                                    program_options regex system thread )
 
     if( NOT Boost_FOUND )
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 549a2c8..b3d4228 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -264,6 +264,8 @@ endif()
 
 set( COMMON_SRCS
     ${COMMON_SRCS}
+    system/libcontext.cpp
+
     kicad_curl/kicad_curl.cpp
     kicad_curl/kicad_curl_easy.cpp
 
diff --git a/common/system/libcontext.cpp b/common/system/libcontext.cpp
new file mode 100644
index 0000000..1f12853
--- /dev/null
+++ b/common/system/libcontext.cpp
@@ -0,0 +1,712 @@
+/*
+
+    auto-generated file, do not modify!
+    libcontext - a slightly more portable version of boost::context
+    Copyright Martin Husemann 2013.
+    Copyright Oliver Kowalke 2009.
+    Copyright Sergue E. Leontiev 2013
+    Copyright Thomas Sailer 2013.
+    Minor modifications by Tomasz Wlostowski 2016.
+
+ Distributed under the Boost Software License, Version 1.0.
+      (See accompanying file LICENSE_1_0.txt or copy at
+            http://www.boost.org/LICENSE_1_0.txt)
+
+*/
+#include <system/libcontext.h>
+
+#if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".p2align 4,,15\n"
+".globl	_jump_fcontext\n"
+".def	_jump_fcontext;	.scl	2;	.type	32;	.endef\n"
+"_jump_fcontext:\n"
+"    mov    0x10(%esp),%ecx\n"
+"    push   %ebp\n"
+"    push   %ebx\n"
+"    push   %esi\n"
+"    push   %edi\n"
+"    mov    %fs:0x18,%edx\n"
+"    mov    (%edx),%eax\n"
+"    push   %eax\n"
+"    mov    0x4(%edx),%eax\n"
+"    push   %eax\n"
+"    mov    0x8(%edx),%eax\n"
+"    push   %eax\n"
+"    mov    0xe0c(%edx),%eax\n"
+"    push   %eax\n"
+"    mov    0x10(%edx),%eax\n"
+"    push   %eax\n"
+"    lea    -0x8(%esp),%esp\n"
+"    test   %ecx,%ecx\n"
+"    je     nxt1\n"
+"    stmxcsr (%esp)\n"
+"    fnstcw 0x4(%esp)\n"
+"nxt1:\n"
+"    mov    0x30(%esp),%eax\n"
+"    mov    %esp,(%eax)\n"
+"    mov    0x34(%esp),%edx\n"
+"    mov    0x38(%esp),%eax\n"
+"    mov    %edx,%esp\n"
+"    test   %ecx,%ecx\n"
+"    je     nxt2\n"
+"    ldmxcsr (%esp)\n"
+"    fldcw  0x4(%esp)\n"
+"nxt2:\n"
+"    lea    0x8(%esp),%esp\n"
+"    mov    %fs:0x18,%edx\n"
+"    pop    %ecx\n"
+"    mov    %ecx,0x10(%edx)\n"
+"    pop    %ecx\n"
+"    mov    %ecx,0xe0c(%edx)\n"
+"    pop    %ecx\n"
+"    mov    %ecx,0x8(%edx)\n"
+"    pop    %ecx\n"
+"    mov    %ecx,0x4(%edx)\n"
+"    pop    %ecx\n"
+"    mov    %ecx,(%edx)\n"
+"    pop    %edi\n"
+"    pop    %esi\n"
+"    pop    %ebx\n"
+"    pop    %ebp\n"
+"    pop    %edx\n"
+"    mov    %eax,0x4(%esp)\n"
+"    jmp    *%edx\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".p2align 4,,15\n"
+".globl	_make_fcontext\n"
+".def	_make_fcontext;	.scl	2;	.type	32;	.endef\n"
+"_make_fcontext:\n"
+"mov    0x4(%esp),%eax\n"
+"lea    -0x8(%eax),%eax\n"
+"and    $0xfffffff0,%eax\n"
+"lea    -0x3c(%eax),%eax\n"
+"mov    0x4(%esp),%ecx\n"
+"mov    %ecx,0x14(%eax)\n"
+"mov    0x8(%esp),%edx\n"
+"neg    %edx\n"
+"lea    (%ecx,%edx,1),%ecx\n"
+"mov    %ecx,0x10(%eax)\n"
+"mov    %ecx,0xc(%eax)\n"
+"mov    0xc(%esp),%ecx\n"
+"mov    %ecx,0x2c(%eax)\n"
+"stmxcsr (%eax)\n"
+"fnstcw 0x4(%eax)\n"
+"mov    $finish,%ecx\n"
+"mov    %ecx,0x30(%eax)\n"
+"mov    %fs:0x0,%ecx\n"
+"walk:\n"
+"mov    (%ecx),%edx\n"
+"inc    %edx\n"
+"je     found\n"
+"dec    %edx\n"
+"xchg   %edx,%ecx\n"
+"jmp    walk\n"
+"found:\n"
+"mov    0x4(%ecx),%ecx\n"
+"mov    %ecx,0x3c(%eax)\n"
+"mov    $0xffffffff,%ecx\n"
+"mov    %ecx,0x38(%eax)\n"
+"lea    0x38(%eax),%ecx\n"
+"mov    %ecx,0x18(%eax)\n"
+"ret\n"
+"finish:\n"
+"xor    %eax,%eax\n"
+"mov    %eax,(%esp)\n"
+"call   _exit\n"
+"hlt\n"
+".def	__exit;	.scl	2;	.type	32;	.endef  \n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_windows_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".p2align 4,,15\n"
+".globl	jump_fcontext\n"
+".def	jump_fcontext;	.scl	2;	.type	32;	.endef\n"
+".seh_proc	jump_fcontext\n"
+"jump_fcontext:\n"
+".seh_endprologue\n"
+"	push   %rbp\n"
+"	push   %rbx\n"
+"	push   %rsi\n"
+"	push   %rdi\n"
+"	push   %r15\n"
+"	push   %r14\n"
+"	push   %r13\n"
+"	push   %r12\n"
+"	mov    %gs:0x30,%r10\n"
+"	mov    0x8(%r10),%rax\n"
+"	push   %rax\n"
+"	mov    0x10(%r10),%rax\n"
+"	push   %rax\n"
+"	mov    0x1478(%r10),%rax\n"
+"	push   %rax\n"
+"	mov    0x18(%r10),%rax\n"
+"	push   %rax\n"
+"	lea    -0xa8(%rsp),%rsp\n"
+"	test   %r9,%r9\n"
+"	je     nxt1\n"
+"	stmxcsr 0xa0(%rsp)\n"
+"	fnstcw 0xa4(%rsp)\n"
+"	movaps %xmm6,(%rsp)\n"
+"	movaps %xmm7,0x10(%rsp)\n"
+"	movaps %xmm8,0x20(%rsp)\n"
+"	movaps %xmm9,0x30(%rsp)\n"
+"	movaps %xmm10,0x40(%rsp)\n"
+"	movaps %xmm11,0x50(%rsp)\n"
+"	movaps %xmm12,0x60(%rsp)\n"
+"	movaps %xmm13,0x70(%rsp)\n"
+"	movaps %xmm14,0x80(%rsp)\n"
+"	movaps %xmm15,0x90(%rsp)\n"
+"nxt1:\n"
+"	xor    %r10,%r10\n"
+"	push   %r10\n"
+"	mov    %rsp,(%rcx)\n"
+"	mov    %rdx,%rsp\n"
+"	pop    %r10\n"
+"	test   %r9,%r9\n"
+"	je     nxt2\n"
+"	ldmxcsr 0xa0(%rsp)\n"
+"	fldcw  0xa4(%rsp)\n"
+"	movaps (%rsp),%xmm6\n"
+"	movaps 0x10(%rsp),%xmm7\n"
+"	movaps 0x20(%rsp),%xmm8\n"
+"	movaps 0x30(%rsp),%xmm9\n"
+"	movaps 0x40(%rsp),%xmm10\n"
+"	movaps 0x50(%rsp),%xmm11\n"
+"	movaps 0x60(%rsp),%xmm12\n"
+"	movaps 0x70(%rsp),%xmm13\n"
+"	movaps 0x80(%rsp),%xmm14\n"
+"	movaps 0x90(%rsp),%xmm15\n"
+"nxt2:\n"
+"	mov    $0xa8,%rcx\n"
+"    test   %r10,%r10\n"
+"    je     nxt3\n"
+"    add    $0x8,%rcx\n"
+"nxt3:\n"
+"	lea    (%rsp,%rcx,1),%rsp\n"
+"	mov    %gs:0x30,%r10\n"
+"	pop    %rax\n"
+"	mov    %rax,0x18(%r10)\n"
+"	pop    %rax\n"
+"	mov    %rax,0x1478(%r10)\n"
+"	pop    %rax\n"
+"	mov    %rax,0x10(%r10)\n"
+"	pop    %rax\n"
+"	mov    %rax,0x8(%r10)\n"
+"	pop    %r12\n"
+"	pop    %r13\n"
+"	pop    %r14\n"
+"	pop    %r15\n"
+"	pop    %rdi\n"
+"	pop    %rsi\n"
+"	pop    %rbx\n"
+"	pop    %rbp\n"
+"	pop    %r10\n"
+"	mov    %r8,%rax\n"
+"	mov    %r8,%rcx\n"
+"	jmpq   *%r10\n"
+".seh_endproc\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_windows_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".p2align 4,,15\n"
+".globl	make_fcontext\n"
+".def	make_fcontext;	.scl	2;	.type	32;	.endef\n"
+".seh_proc	make_fcontext\n"
+"make_fcontext:\n"
+".seh_endprologue\n"
+"mov    %rcx,%rax\n"
+"sub    $0x28,%rax\n"
+"and    $0xfffffffffffffff0,%rax\n"
+"sub    $0x128,%rax\n"
+"mov    %r8,0x118(%rax)\n"
+"mov    %rcx,0xd0(%rax)\n"
+"neg    %rdx\n"
+"lea    (%rcx,%rdx,1),%rcx\n"
+"mov    %rcx,0xc8(%rax)\n"
+"mov    %rcx,0xc0(%rax)\n"
+"stmxcsr 0xa8(%rax)\n"
+"fnstcw 0xac(%rax)\n"
+"leaq  finish(%rip), %rcx\n"
+"mov    %rcx,0x120(%rax)\n"
+"mov    $0x1,%rcx\n"
+"mov    %rcx,(%rax)\n"
+"retq\n"
+"finish:\n"
+"xor    %rcx,%rcx\n"
+"callq  0x63\n"
+"hlt\n"
+"   .seh_endproc\n"
+".def	_exit;	.scl	2;	.type	32;	.endef  \n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_i386) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl jump_fcontext\n"
+".align 2\n"
+".type jump_fcontext,@function\n"
+"jump_fcontext:\n"
+"    movl  0x10(%esp), %ecx\n"
+"    pushl  %ebp  \n"
+"    pushl  %ebx  \n"
+"    pushl  %esi  \n"
+"    pushl  %edi  \n"
+"    leal  -0x8(%esp), %esp\n"
+"    test  %ecx, %ecx\n"
+"    je  1f\n"
+"    stmxcsr  (%esp)\n"
+"    fnstcw  0x4(%esp)\n"
+"1:\n"
+"    movl  0x1c(%esp), %eax\n"
+"    movl  %esp, (%eax)\n"
+"    movl  0x20(%esp), %edx\n"
+"    movl  0x24(%esp), %eax\n"
+"    movl  %edx, %esp\n"
+"    test  %ecx, %ecx\n"
+"    je  2f\n"
+"    ldmxcsr  (%esp)\n"
+"    fldcw  0x4(%esp)\n"
+"2:\n"
+"    leal  0x8(%esp), %esp\n"
+"    popl  %edi  \n"
+"    popl  %esi  \n"
+"    popl  %ebx  \n"
+"    popl  %ebp  \n"
+"    popl  %edx\n"
+"    movl  %eax, 0x4(%esp)\n"
+"    jmp  *%edx\n"
+".size jump_fcontext,.-jump_fcontext\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_i386) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl make_fcontext\n"
+".align 2\n"
+".type make_fcontext,@function\n"
+"make_fcontext:\n"
+"    movl  0x4(%esp), %eax\n"
+"    leal  -0x8(%eax), %eax\n"
+"    andl  $-16, %eax\n"
+"    leal  -0x20(%eax), %eax\n"
+"    movl  0xc(%esp), %edx\n"
+"    movl  %edx, 0x18(%eax)\n"
+"    stmxcsr  (%eax)\n"
+"    fnstcw  0x4(%eax)\n"
+"    call  1f\n"
+"1:  popl  %ecx\n"
+"    addl  $finish-1b, %ecx\n"
+"    movl  %ecx, 0x1c(%eax)\n"
+"    ret \n"
+"finish:\n"
+"    call  2f\n"
+"2:  popl  %ebx\n"
+"    addl  $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx\n"
+"    xorl  %eax, %eax\n"
+"    movl  %eax, (%esp)\n"
+"    call  _exit@PLT\n"
+"    hlt\n"
+".size make_fcontext,.-make_fcontext\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl jump_fcontext\n"
+".type jump_fcontext,@function\n"
+".align 16\n"
+"jump_fcontext:\n"
+"    pushq  %rbp  \n"
+"    pushq  %rbx  \n"
+"    pushq  %r15  \n"
+"    pushq  %r14  \n"
+"    pushq  %r13  \n"
+"    pushq  %r12  \n"
+"    leaq  -0x8(%rsp), %rsp\n"
+"    cmp  $0, %rcx\n"
+"    je  1f\n"
+"    stmxcsr  (%rsp)\n"
+"    fnstcw   0x4(%rsp)\n"
+"1:\n"
+"    movq  %rsp, (%rdi)\n"
+"    movq  %rsi, %rsp\n"
+"    cmp  $0, %rcx\n"
+"    je  2f\n"
+"    ldmxcsr  (%rsp)\n"
+"    fldcw  0x4(%rsp)\n"
+"2:\n"
+"    leaq  0x8(%rsp), %rsp\n"
+"    popq  %r12  \n"
+"    popq  %r13  \n"
+"    popq  %r14  \n"
+"    popq  %r15  \n"
+"    popq  %rbx  \n"
+"    popq  %rbp  \n"
+"    popq  %r8\n"
+"    movq  %rdx, %rax\n"
+"    movq  %rdx, %rdi\n"
+"    jmp  *%r8\n"
+".size jump_fcontext,.-jump_fcontext\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl make_fcontext\n"
+".type make_fcontext,@function\n"
+".align 16\n"
+"make_fcontext:\n"
+"    movq  %rdi, %rax\n"
+"    andq  $-16, %rax\n"
+"    leaq  -0x48(%rax), %rax\n"
+"    movq  %rdx, 0x38(%rax)\n"
+"    stmxcsr  (%rax)\n"
+"    fnstcw   0x4(%rax)\n"
+"    leaq  finish(%rip), %rcx\n"
+"    movq  %rcx, 0x40(%rax)\n"
+"    ret \n"
+"finish:\n"
+"    xorq  %rdi, %rdi\n"
+"    call  _exit@PLT\n"
+"    hlt\n"
+".size make_fcontext,.-make_fcontext\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_apple_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl _jump_fcontext\n"
+".align 8\n"
+"_jump_fcontext:\n"
+"    pushq  %rbp  \n"
+"    pushq  %rbx  \n"
+"    pushq  %r15  \n"
+"    pushq  %r14  \n"
+"    pushq  %r13  \n"
+"    pushq  %r12  \n"
+"    leaq  -0x8(%rsp), %rsp\n"
+"    cmp  $0, %rcx\n"
+"    je  1f\n"
+"    stmxcsr  (%rsp)\n"
+"    fnstcw   0x4(%rsp)\n"
+"1:\n"
+"    movq  %rsp, (%rdi)\n"
+"    movq  %rsi, %rsp\n"
+"    cmp  $0, %rcx\n"
+"    je  2f\n"
+"    ldmxcsr  (%rsp)\n"
+"    fldcw  0x4(%rsp)\n"
+"2:\n"
+"    leaq  0x8(%rsp), %rsp\n"
+"    popq  %r12  \n"
+"    popq  %r13  \n"
+"    popq  %r14  \n"
+"    popq  %r15  \n"
+"    popq  %rbx  \n"
+"    popq  %rbp  \n"
+"    popq  %r8\n"
+"    movq  %rdx, %rax\n"
+"    movq  %rdx, %rdi\n"
+"    jmp  *%r8\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_apple_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl _make_fcontext\n"
+".align 8\n"
+"_make_fcontext:\n"
+"    movq  %rdi, %rax\n"
+"    movabs  $-16,           %r8\n"
+"    andq    %r8,            %rax\n"
+"    leaq  -0x48(%rax), %rax\n"
+"    movq  %rdx, 0x38(%rax)\n"
+"    stmxcsr  (%rax)\n"
+"    fnstcw   0x4(%rax)\n"
+"    leaq  finish(%rip), %rcx\n"
+"    movq  %rcx, 0x40(%rax)\n"
+"    ret \n"
+"finish:\n"
+"    xorq  %rdi, %rdi\n"
+"    call  __exit\n"
+"    hlt\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_apple_i386) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl _jump_fcontext\n"
+".align 2\n"
+"_jump_fcontext:\n"
+"    movl  0x10(%esp), %ecx\n"
+"    pushl  %ebp  \n"
+"    pushl  %ebx  \n"
+"    pushl  %esi  \n"
+"    pushl  %edi  \n"
+"    leal  -0x8(%esp), %esp\n"
+"    test  %ecx, %ecx\n"
+"    je  1f\n"
+"    stmxcsr  (%esp)\n"
+"    fnstcw  0x4(%esp)\n"
+"1:\n"
+"    movl  0x1c(%esp), %eax\n"
+"    movl  %esp, (%eax)\n"
+"    movl  0x20(%esp), %edx\n"
+"    movl  0x24(%esp), %eax\n"
+"    movl  %edx, %esp\n"
+"    test  %ecx, %ecx\n"
+"    je  2f\n"
+"    ldmxcsr  (%esp)\n"
+"    fldcw  0x4(%esp)\n"
+"2:\n"
+"    leal  0x8(%esp), %esp\n"
+"    popl  %edi  \n"
+"    popl  %esi  \n"
+"    popl  %ebx  \n"
+"    popl  %ebp  \n"
+"    popl  %edx\n"
+"    movl  %eax, 0x4(%esp)\n"
+"    jmp  *%edx\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_apple_i386) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl _make_fcontext\n"
+".align 2\n"
+"_make_fcontext:\n"
+"    movl  0x4(%esp), %eax\n"
+"    leal  -0x8(%eax), %eax\n"
+"    andl  $-16, %eax\n"
+"    leal  -0x20(%eax), %eax\n"
+"    movl  0xc(%esp), %edx\n"
+"    movl  %edx, 0x18(%eax)\n"
+"    stmxcsr  (%eax)\n"
+"    fnstcw  0x4(%eax)\n"
+"    call  1f\n"
+"1:  popl  %ecx\n"
+"    addl  $finish-1b, %ecx\n"
+"    movl  %ecx, 0x1c(%eax)\n"
+"    ret \n"
+"finish:\n"
+"    xorl  %eax, %eax\n"
+"    movl  %eax, (%esp)\n"
+"    call  __exit\n"
+"    hlt\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl jump_fcontext\n"
+".align 2\n"
+".type jump_fcontext,%function\n"
+"jump_fcontext:\n"
+"    @ save LR as PC\n"
+"    push {lr}\n"
+"    @ save V1-V8,LR\n"
+"    push {v1-v8,lr}\n"
+"    @ prepare stack for FPU\n"
+"    sub  sp, sp, #64\n"
+"    @ test if fpu env should be preserved\n"
+"    cmp  a4, #0\n"
+"    beq  1f\n"
+"    @ save S16-S31\n"
+"    vstmia  sp, {d8-d15}\n"
+"1:\n"
+"    @ store RSP (pointing to context-data) in A1\n"
+"    str  sp, [a1]\n"
+"    @ restore RSP (pointing to context-data) from A2\n"
+"    mov  sp, a2\n"
+"    @ test if fpu env should be preserved\n"
+"    cmp  a4, #0\n"
+"    beq  2f\n"
+"    @ restore S16-S31\n"
+"    vldmia  sp, {d8-d15}\n"
+"2:\n"
+"    @ prepare stack for FPU\n"
+"    add  sp, sp, #64\n"
+"    @ use third arg as return value after jump\n"
+"    @ and as first arg in context function\n"
+"    mov  a1, a3\n"
+"    @ restore v1-V8,LR,PC\n"
+"    pop {v1-v8,lr}\n"
+"    pop {pc}\n"
+".size jump_fcontext,.-jump_fcontext\n"
+"@ Mark that we don't need executable stack.\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl make_fcontext\n"
+".align 2\n"
+".type make_fcontext,%function\n"
+"make_fcontext:\n"
+"    @ shift address in A1 to lower 16 byte boundary\n"
+"    bic  a1, a1, #15\n"
+"    @ reserve space for context-data on context-stack\n"
+"    sub  a1, a1, #104\n"
+"    @ third arg of make_fcontext() == address of context-function\n"
+"    str  a3, [a1,#100]\n"
+"    @ compute abs address of label finish\n"
+"    adr  a2, finish\n"
+"    @ save address of finish as return-address for context-function\n"
+"    @ will be entered after context-function returns\n"
+"    str  a2, [a1,#96]\n"
+"    bx  lr @ return pointer to context-data\n"
+"finish:\n"
+"    @ exit code is zero\n"
+"    mov  a1, #0\n"
+"    @ exit application\n"
+"    bl  _exit@PLT\n"
+".size make_fcontext,.-make_fcontext\n"
+"@ Mark that we don't need executable stack.\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_arm64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".cpu    generic+fp+simd\n"
+".text\n"
+".align  2\n"
+".global jump_fcontext\n"
+".type   jump_fcontext, %function\n"
+"jump_fcontext:\n"
+"    # prepare stack for GP + FPU\n"
+"    sub  sp, sp, #0xb0\n"
+"# Because gcc may save integer registers in fp registers across a\n"
+"# function call we cannot skip saving the fp registers.\n"
+"#\n"
+"# Do not reinstate this test unless you fully understand what you\n"
+"# are doing.\n"
+"#\n"
+"#    # test if fpu env should be preserved\n"
+"#    cmp  w3, #0\n"
+"#    b.eq  1f\n"
+"    # save d8 - d15\n"
+"    stp  d8,  d9,  [sp, #0x00]\n"
+"    stp  d10, d11, [sp, #0x10]\n"
+"    stp  d12, d13, [sp, #0x20]\n"
+"    stp  d14, d15, [sp, #0x30]\n"
+"1:\n"
+"    # save x19-x30\n"
+"    stp  x19, x20, [sp, #0x40]\n"
+"    stp  x21, x22, [sp, #0x50]\n"
+"    stp  x23, x24, [sp, #0x60]\n"
+"    stp  x25, x26, [sp, #0x70]\n"
+"    stp  x27, x28, [sp, #0x80]\n"
+"    stp  x29, x30, [sp, #0x90]\n"
+"    # save LR as PC\n"
+"    str  x30, [sp, #0xa0]\n"
+"    # store RSP (pointing to context-data) in first argument (x0).\n"
+"    # STR cannot have sp as a target register\n"
+"    mov  x4, sp\n"
+"    str  x4, [x0]\n"
+"    # restore RSP (pointing to context-data) from A2 (x1)\n"
+"    mov  sp, x1\n"
+"#    # test if fpu env should be preserved\n"
+"#    cmp  w3, #0\n"
+"#    b.eq  2f\n"
+"    # load d8 - d15\n"
+"    ldp  d8,  d9,  [sp, #0x00]\n"
+"    ldp  d10, d11, [sp, #0x10]\n"
+"    ldp  d12, d13, [sp, #0x20]\n"
+"    ldp  d14, d15, [sp, #0x30]\n"
+"2:\n"
+"    # load x19-x30\n"
+"    ldp  x19, x20, [sp, #0x40]\n"
+"    ldp  x21, x22, [sp, #0x50]\n"
+"    ldp  x23, x24, [sp, #0x60]\n"
+"    ldp  x25, x26, [sp, #0x70]\n"
+"    ldp  x27, x28, [sp, #0x80]\n"
+"    ldp  x29, x30, [sp, #0x90]\n"
+"    # use third arg as return value after jump\n"
+"    # and as first arg in context function\n"
+"    mov  x0, x2\n"
+"    # load pc\n"
+"    ldr  x4, [sp, #0xa0]\n"
+"    # restore stack from GP + FPU\n"
+"    add  sp, sp, #0xb0\n"
+"    ret x4\n"
+".size   jump_fcontext,.-jump_fcontext\n"
+"# Mark that we don't need executable stack.\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_arm64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".cpu    generic+fp+simd\n"
+".text\n"
+".align  2\n"
+".global make_fcontext\n"
+".type   make_fcontext, %function\n"
+"make_fcontext:\n"
+"    # shift address in x0 (allocated stack) to lower 16 byte boundary\n"
+"    and x0, x0, ~0xF\n"
+"    # reserve space for context-data on context-stack\n"
+"    sub  x0, x0, #0xb0\n"
+"    # third arg of make_fcontext() == address of context-function\n"
+"    # store address as a PC to jump in\n"
+"    str  x2, [x0, #0xa0]\n"
+"    # save address of finish as return-address for context-function\n"
+"    # will be entered after context-function returns (LR register)\n"
+"    adr  x1, finish\n"
+"    str  x1, [x0, #0x98]\n"
+"    ret  x30 \n"
+"finish:\n"
+"    # exit code is zero\n"
+"    mov  x0, #0\n"
+"    # exit application\n"
+"    bl  _exit\n"
+".size   make_fcontext,.-make_fcontext\n"
+"# Mark that we don't need executable stack.\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp
index 447ab99..1ebe676 100644
--- a/common/tool/tool_manager.cpp
+++ b/common/tool/tool_manager.cpp
@@ -485,7 +485,7 @@ optional<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool,
     st->waitEvents = aConditions;
 
     // switch context back to event dispatcher loop
-    st->cofunc->Yield();
+    st->cofunc->KiYield();
 
     return st->wakeupEvent;
 }
diff --git a/include/system/libcontext.h b/include/system/libcontext.h
new file mode 100644
index 0000000..1cb5d71
--- /dev/null
+++ b/include/system/libcontext.h
@@ -0,0 +1,96 @@
+/*
+ *
+ *   libcontext - a slightly more portable version of boost::context
+ *
+ *   Copyright Martin Husemann 2013.
+ *   Copyright Oliver Kowalke 2009.
+ *   Copyright Sergue E. Leontiev 2013.
+ *   Copyright Thomas Sailer 2013.
+ *   Minor modifications by Tomasz Wlostowski 2016.
+ *
+ *  Distributed under the Boost Software License, Version 1.0.
+ *     (See accompanying file LICENSE_1_0.txt or copy at
+ *           http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#ifndef __LIBCONTEXT_H
+#define __LIBCONTEXT_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+
+
+#if defined(__GNUC__) || defined(__APPLE__)
+
+    #define LIBCONTEXT_COMPILER_gcc
+
+    #if defined(__linux__)
+    #ifdef __x86_64__
+        #define LIBCONTEXT_PLATFORM_linux_x86_64
+        #define LIBCONTEXT_CALL_CONVENTION
+
+    #elif __i386__
+        #define LIBCONTEXT_PLATFORM_linux_i386
+        #define LIBCONTEXT_CALL_CONVENTION
+    #elif __arm__
+        #define LIBCONTEXT_PLATFORM_linux_arm32
+        #define LIBCONTEXT_CALL_CONVENTION
+    #elif __aarch64__
+        #define LIBCONTEXT_PLATFORM_linux_arm64
+        #define LIBCONTEXT_CALL_CONVENTION
+    #endif
+
+    #elif defined(__MINGW32__) || defined(__MINGW64__)
+    #if defined(__x86_64__)
+        #define LIBCONTEXT_COMPILER_gcc
+            #define LIBCONTEXT_PLATFORM_windows_x86_64
+        #define LIBCONTEXT_CALL_CONVENTION
+    #endif
+
+    #if defined(__i386__)
+        #define LIBCONTEXT_COMPILER_gcc
+        #define LIBCONTEXT_PLATFORM_windows_i386
+        #define LIBCONTEXT_CALL_CONVENTION __cdecl
+    #endif
+    #elif defined(__APPLE__) && defined(__MACH__)
+    #if defined(__i386__)
+        #define LIBCONTEXT_PLATFORM_apple_i386
+        #define LIBCONTEXT_CALL_CONVENTION
+    #elif defined(__x86_64__)
+        #define LIBCONTEXT_PLATFORM_apple_x86_64
+        #define LIBCONTEXT_CALL_CONVENTION
+    #endif
+    #endif
+#endif
+
+#ifdef __cplusplus
+namespace libcontext {
+#endif
+
+#if defined(_WIN32_WCE)
+typedef int intptr_t;
+#endif
+
+typedef void* fcontext_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+intptr_t LIBCONTEXT_CALL_CONVENTION jump_fcontext( fcontext_t* ofc, fcontext_t nfc,
+        intptr_t vp, bool preserve_fpu = false );
+fcontext_t LIBCONTEXT_CALL_CONVENTION make_fcontext( void* sp, size_t size,
+        void (* fn)( intptr_t ) );
+
+#ifdef __cplusplus
+};    // namespace
+#endif
+
+#ifdef __cplusplus
+};    // extern "C"
+#endif
+
+#endif
diff --git a/include/tool/coroutine.h b/include/tool/coroutine.h
index c7eaf5f..7504329 100644
--- a/include/tool/coroutine.h
+++ b/include/tool/coroutine.h
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2013 CERN
  * @author Tomasz Wlostowski <tomasz.wlostowski@xxxxxxx>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,10 +28,10 @@
 
 #include <cstdlib>
 
-#include <boost/context/fcontext.hpp>
-#include <boost/version.hpp>
+#include <type_traits>
 
-#include "delegate.h"
+#include <system/libcontext.h>
+#include <memory>
 
 /**
  *  Class COROUNTINE.
@@ -45,7 +46,7 @@
  *  preempted only when it deliberately yields the control to the caller. This way,
  *  we avoid concurrency problems such as locking / race conditions.
  *
- *  Uses boost::context library to do the actual context switching.
+ *  Uses libcontext library to do the actual context switching.
  *
  *  This particular version takes a DELEGATE as an entry point, so it can invoke
  *  methods within a given object as separate coroutines.
@@ -53,13 +54,66 @@
  *  See coroutine_example.cpp for sample code.
  */
 
-template <class ReturnType, class ArgType>
+template <typename ReturnType, typename ArgType>
 class COROUTINE
 {
+private:
+    class CALL_CONTEXT;
+
+    struct INVOCATION_ARGS
+    {
+        enum
+        {
+            FROM_ROOT,      // a stub was called/a corutine was resumed from the main-stack context
+            FROM_ROUTINE,   // a stub was called/a coroutine was resumed fron a coroutine context
+            CONTINUE_AFTER_ROOT // a function sent a request to invoke a function on the main
+                                // stack context
+        } type; // invocation type
+        COROUTINE*    destination;  // stores the coroutine pointer for the stub OR the coroutine
+                                    // ptr for the coroutine to be resumed if a
+                                    // root(main-stack)-call-was initiated.
+        CALL_CONTEXT* context;      // pointer to the call context of the current callgraph this
+                                    // call context holds a reference to the main stack context
+    };
+
+    using CONTEXT_T = libcontext::fcontext_t;
+    using CALLEE_STORAGE = CONTEXT_T;
+
+    class CALL_CONTEXT
+    {
+    public:
+        void SetMainStack( CONTEXT_T* aStack )
+        {
+            m_mainStackContext = aStack;
+        }
+
+        void RunMainStack( COROUTINE* aCor, std::function<void()> aFunc )
+        {
+            m_mainStackFunction = std::move( aFunc );
+            INVOCATION_ARGS args{ INVOCATION_ARGS::CONTINUE_AFTER_ROOT, aCor, this };
+
+            libcontext::jump_fcontext( &aCor->m_callee, *m_mainStackContext,
+                reinterpret_cast<intptr_t>( &args ) );
+        }
+
+        void Continue( INVOCATION_ARGS* args )
+        {
+            while( args->type == INVOCATION_ARGS::CONTINUE_AFTER_ROOT )
+            {
+                m_mainStackFunction();
+                args->type = INVOCATION_ARGS::FROM_ROOT;
+                args = args->destination->doResume( args );
+            }
+        }
+
+    private:
+        CONTEXT_T*              m_mainStackContext;
+        std::function<void()>   m_mainStackFunction;
+    };
+
 public:
     COROUTINE() :
-        m_saved( NULL ), m_self( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize ),
-        m_running( false )
+        COROUTINE( nullptr )
     {
     }
 
@@ -68,9 +122,8 @@ public:
      * Creates a coroutine from a member method of an object
      */
     template <class T>
-    COROUTINE( T* object, ReturnType(T::* ptr)( ArgType ) ) :
-        m_func( object, ptr ), m_self( NULL ), m_saved( NULL ), m_stack( NULL ),
-        m_stackSize( c_defaultStackSize ), m_running( false )
+    COROUTINE( T* object, ReturnType(T::*ptr)( ArgType ) ) :
+        COROUTINE( std::bind( ptr, object, std::placeholders::_1 ) )
     {
     }
 
@@ -78,51 +131,42 @@ public:
      * Constructor
      * Creates a coroutine from a delegate object
      */
-    COROUTINE( DELEGATE<ReturnType, ArgType> aEntry ) :
-        m_func( aEntry ), m_saved( NULL ), m_self( NULL ), m_stack( NULL ),
-        m_stackSize( c_defaultStackSize ), m_running( false )
+    COROUTINE( std::function<ReturnType(ArgType)> aEntry ) :
+        m_func( std::move( aEntry ) ),
+        m_running( false ),
+        m_args( 0 ),
+        m_callee( nullptr ),
+        m_retVal( 0 )
     {
-        // Avoid not initialized members, and make static analysers quiet
-        m_args = 0;
-        m_retVal = 0;
     }
 
     ~COROUTINE()
     {
-        if( m_saved )
-            delete m_saved;
-
-#if BOOST_VERSION >= 105600
-        if( m_self )
-            delete m_self;
-#endif
-
-        if( m_stack )
-            free( m_stack );
     }
 
+public:
     /**
-     * Function Yield()
+     * Function KiYield()
      *
      * Stops execution of the coroutine and returns control to the caller.
      * After a yield, Call() or Resume() methods invoked by the caller will
      * immediately return true, indicating that we are not done yet, just asleep.
      */
-    void Yield()
+    void KiYield()
     {
-        jump( m_self, m_saved, 0 );
+        jumpOut();
     }
 
     /**
-     * Function Yield()
+     * Function KiYield()
      *
-     * Yield with a value - passes a value of given type to the caller.
+     * KiYield with a value - passes a value of given type to the caller.
      * Useful for implementing generator objects.
      */
-    void Yield( ReturnType& aRetVal )
+    void KiYield( ReturnType& aRetVal )
     {
         m_retVal = aRetVal;
-        jump( m_self, m_saved, 0 );
+        jumpOut();
     }
 
     /**
@@ -130,64 +174,97 @@ public:
      *
      * Defines the entry point for the coroutine, if not set in the constructor.
      */
-    void SetEntry( DELEGATE<ReturnType, ArgType> aEntry )
+    void SetEntry( std::function<ReturnType(ArgType)> aEntry )
     {
-        m_func = aEntry;
+        m_func = std::move( aEntry );
     }
 
-    /* Function Call()
+    /**
+     * Function RunMainStack()
      *
-     * Starts execution of a coroutine, passing args as its arguments.
-     * @return true, if the coroutine has yielded and false if it has finished its
-     * execution (returned).
+     * Run a functor inside the application main stack context
+     * Call this function for example if the operation will spawn a webkit browser instance which
+     * will walk the stack to the upper border of the address space on mac osx systems because
+     * its javascript needs garbage collection (for example if you paste text into an edit box).
      */
-    bool Call( ArgType aArgs )
+    void RunMainStack( std::function<void()> func )
     {
-        // fixme: Clean up stack stuff. Add a guard
-        m_stack = malloc( c_defaultStackSize );
-
-        // align to 16 bytes
-        void* sp = (void*) ( ( ( (ptrdiff_t) m_stack ) + m_stackSize - 0xf ) & ( ~0x0f ) );
+        assert( m_callContext );
+        m_callContext->RunMainStack( this, std::move( func ) );
+    }
 
-        // correct the stack size
-        m_stackSize -= ( (size_t) m_stack + m_stackSize - (size_t) sp );
+   /**
+    * Function Call()
+    *
+    * Starts execution of a coroutine, passing args as its arguments. Call this method
+    * from the application main stack only.
+    * @return true, if the coroutine has yielded and false if it has finished its
+    * execution (returned).
+    */
+    bool Call( ArgType aArg )
+    {
+        CALL_CONTEXT ctx;
+        INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
+        ctx.Continue( doCall( &args, aArg ) );
 
-        assert( m_self == NULL );
-        assert( m_saved == NULL );
+        return Running();
+    }
 
-        m_args = &aArgs;
-#if BOOST_VERSION >= 105600
-        m_self = new boost::context::fcontext_t();
-        *m_self = boost::context::make_fcontext( sp, m_stackSize, callerStub );
-#else
-        m_self = boost::context::make_fcontext( sp, m_stackSize, callerStub );
-#endif
-        m_saved = new boost::context::fcontext_t();
+   /**
+    * Function Call()
+    *
+    * Starts execution of a coroutine, passing args as its arguments. Call this method
+    * for a nested coroutine invocation.
+    * @return true, if the coroutine has yielded and false if it has finished its
+    * execution (returned).
+    */
+    bool Call( const COROUTINE& aCor, ArgType aArg )
+    {
+        INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, this, aCor.m_callContext };
+        doCall( &args, aArg );
+        // we will not be asked to continue
 
-        m_running = true;
-        // off we go!
-        jump( m_saved, m_self, reinterpret_cast<intptr_t>( this ) );
-        return m_running;
+        return Running();
     }
 
     /**
-     * Function Resume()
-     *
-     * Resumes execution of a previously yielded coroutine.
-     * @return true, if the coroutine has yielded again and false if it has finished its
-     * execution (returned).
-     */
+    * Function Resume()
+    *
+    * Resumes execution of a previously yielded coroutine. Call this method only
+    * from the main application stack.
+    * @return true, if the coroutine has yielded again and false if it has finished its
+    * execution (returned).
+    */
     bool Resume()
     {
-        jump( m_saved, m_self, 0 );
+        CALL_CONTEXT ctx;
+        INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
+        ctx.Continue( doResume( &args ) );
 
-        return m_running;
+        return Running();
+    }
+
+    /**
+    * Function Resume()
+    *
+    * Resumes execution of a previously yielded coroutine. Call this method
+    * for a nested coroutine invocation.
+    * @return true, if the coroutine has yielded again and false if it has finished its
+    * execution (returned).
+    */
+    bool Resume( const COROUTINE& aCor )
+    {
+        INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, this, aCor.m_callContext };
+        doResume( &args );
+        // we will not be asked to continue
+
+        return Running();
     }
 
     /**
      * Function ReturnValue()
      *
-     * Returns the yielded value (the argument Yield() was called with)
+     * Returns the yielded value (the argument KiYield() was called with)
      */
     const ReturnType& ReturnValue() const
     {
@@ -205,64 +282,106 @@ public:
     }
 
 private:
-    static const int c_defaultStackSize = 2000000;    // fixme: make configurable
+    INVOCATION_ARGS* doCall( INVOCATION_ARGS* aInvArgs, ArgType aArgs )
+    {
+        assert( m_func );
+        assert( !m_callee );
+
+        m_args = &aArgs;
+
+        assert( m_stack == nullptr );
+
+        // fixme: Clean up stack stuff. Add a guard
+        size_t stackSize = c_defaultStackSize;
+        m_stack.reset( new char[stackSize] );
+
+        // align to 16 bytes
+        void* sp = (void*)((((ptrdiff_t) m_stack.get()) + stackSize - 0xf) & (~0x0f));
+
+        // correct the stack size
+        stackSize -= size_t( ( (ptrdiff_t) m_stack.get() + stackSize ) - (ptrdiff_t) sp );
+
+        m_callee = libcontext::make_fcontext( sp, stackSize, callerStub );
+        m_running = true;
+
+        // off we go!
+        return jumpIn( aInvArgs );
+    }
+
+    INVOCATION_ARGS* doResume( INVOCATION_ARGS* args )
+    {
+        return jumpIn( args );
+    }
 
     /* real entry point of the coroutine */
     static void callerStub( intptr_t aData )
     {
+        INVOCATION_ARGS& args = *reinterpret_cast<INVOCATION_ARGS*>( aData );
         // get pointer to self
-        COROUTINE<ReturnType, ArgType>* cor = reinterpret_cast<COROUTINE<ReturnType, ArgType>*>( aData );
+        COROUTINE* cor     = args.destination;
+        cor->m_callContext = args.context;
+
+        if( args.type == INVOCATION_ARGS::FROM_ROOT )
+            cor->m_callContext->SetMainStack( &cor->m_caller );
 
         // call the coroutine method
-        cor->m_retVal = cor->m_func( *cor->m_args );
+        cor->m_retVal = cor->m_func( *(cor->m_args) );
         cor->m_running = false;
 
         // go back to wherever we came from.
-        jump( cor->m_self, cor->m_saved, 0 );    // reinterpret_cast<intptr_t>( this ));
+        cor->jumpOut();
     }
 
-    ///> Wrapper for jump_fcontext to assure compatibility between different boost versions
-    static inline intptr_t jump(boost::context::fcontext_t* aOld, boost::context::fcontext_t* aNew,
-                                intptr_t aP, bool aPreserveFPU = true )
+    INVOCATION_ARGS* jumpIn( INVOCATION_ARGS* args )
     {
-#if BOOST_VERSION >= 105600
-        return boost::context::jump_fcontext( aOld, *aNew, aP, aPreserveFPU );
-#else
-        return boost::context::jump_fcontext( aOld, aNew, aP, aPreserveFPU );
-#endif
+        args = reinterpret_cast<INVOCATION_ARGS*>(
+            libcontext::jump_fcontext( &m_caller, m_callee,
+                                           reinterpret_cast<intptr_t>( args ) )
+            );
+
+        return args;
     }
 
-    template <typename T>
-    struct strip_ref
+    void jumpOut()
     {
-        typedef T result;
-    };
+        INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, nullptr, nullptr };
+        INVOCATION_ARGS* ret;
+        ret = reinterpret_cast<INVOCATION_ARGS*>(
+            libcontext::jump_fcontext( &m_callee, m_caller,
+                                           reinterpret_cast<intptr_t>( &args ) )
+            );
+
+        m_callContext = ret->context;
+
+        if( ret->type == INVOCATION_ARGS::FROM_ROOT )
+        {
+            m_callContext->SetMainStack( &m_caller );
+        }
+    }
 
-    template <typename T>
-    struct strip_ref<T&>
-    {
-        typedef T result;
-    };
+    static constexpr int c_defaultStackSize = 2000000;    // fixme: make configurable
+
+    ///< coroutine stack
+    std::unique_ptr<char[]> m_stack;
 
-    DELEGATE<ReturnType, ArgType> m_func;
+    std::function<ReturnType( ArgType )> m_func;
+
+    bool m_running;
 
     ///< pointer to coroutine entry arguments. Stripped of references
     ///< to avoid compiler errors.
-    typename strip_ref<ArgType>::result* m_args;
-    ReturnType m_retVal;
+    typename std::remove_reference<ArgType>::type* m_args;
 
     ///< saved caller context
-    boost::context::fcontext_t* m_saved;
-
-    ///< saved coroutine context
-    boost::context::fcontext_t* m_self;
+    CONTEXT_T m_caller;
 
-    ///< coroutine stack
-    void* m_stack;
+    ///< main stack information
+    CALL_CONTEXT* m_callContext;
 
-    size_t m_stackSize;
+    ///< saved coroutine context
+    CALLEE_STORAGE m_callee;
 
-    bool m_running;
+    ReturnType m_retVal;
 };
 
 #endif

Follow ups

References