mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Better (?) support for Windows TIB.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65867 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
904af4aef2
commit
d97c928067
4 changed files with 40 additions and 17 deletions
|
@ -14,28 +14,38 @@
|
|||
; to touch these in order to pass them to the destination coroutine.
|
||||
|
||||
@coroutine_transfer@8 proc
|
||||
; Save caller registers
|
||||
; Save the thread information block:
|
||||
push fs:[0]
|
||||
push fs:[4]
|
||||
push fs:[8]
|
||||
|
||||
; Save caller registers:
|
||||
push ebp
|
||||
push ebx
|
||||
push edi
|
||||
push esi
|
||||
|
||||
; Save caller stack pointer
|
||||
; Save caller stack pointer:
|
||||
mov dword ptr [ecx], esp
|
||||
|
||||
; Restore callee stack pointer
|
||||
; Restore callee stack pointer:
|
||||
mov esp, dword ptr [edx]
|
||||
|
||||
; Restore callee stack
|
||||
; Restore callee stack:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebx
|
||||
pop ebp
|
||||
|
||||
; Save the first argument as the return value
|
||||
; Restore the thread information block:
|
||||
pop fs:[8]
|
||||
pop fs:[4]
|
||||
pop fs:[0]
|
||||
|
||||
; Save the first argument as the return value:
|
||||
mov eax, dword ptr ecx
|
||||
|
||||
; Jump to the address on the stack
|
||||
; Jump to the address on the stack:
|
||||
ret
|
||||
@coroutine_transfer@8 endp
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ extern "C" {
|
|||
|
||||
#define COROUTINE __declspec(noreturn) void __fastcall
|
||||
|
||||
/* This doesn't include thread information block */
|
||||
const size_t COROUTINE_REGISTERS = 4;
|
||||
|
||||
struct coroutine_context
|
||||
|
@ -40,9 +41,9 @@ static inline void coroutine_initialize(
|
|||
}
|
||||
|
||||
/* Windows Thread Information Block */
|
||||
*--context->stack_pointer = 0;
|
||||
*--context->stack_pointer = stack_pointer;
|
||||
*--context->stack_pointer = (void*)stack_size;
|
||||
*--context->stack_pointer = 0; /* fs:[0] */
|
||||
*--context->stack_pointer = stack_pointer + stack_size; /* fs:[4] */
|
||||
*--context->stack_pointer = (void*)stack_pointer; /* fs:[8] */
|
||||
|
||||
*--context->stack_pointer = (void*)start;
|
||||
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
.code
|
||||
|
||||
coroutine_transfer proc
|
||||
; Save the thread information block:
|
||||
push gs:[0x00]
|
||||
push gs:[0x08]
|
||||
push gs:[0x10]
|
||||
|
||||
; Save caller registers:
|
||||
push rbp
|
||||
push rbx
|
||||
push rdi
|
||||
|
@ -17,13 +23,13 @@ coroutine_transfer proc
|
|||
push r14
|
||||
push r15
|
||||
|
||||
; Save caller stack pointer
|
||||
; Save caller stack pointer:
|
||||
mov [rcx], rsp
|
||||
|
||||
; Restore callee stack pointer
|
||||
; Restore callee stack pointer:
|
||||
mov rsp, [rdx]
|
||||
|
||||
; Restore callee stack
|
||||
; Restore callee stack:
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
|
@ -33,10 +39,15 @@ coroutine_transfer proc
|
|||
pop rbx
|
||||
pop rbp
|
||||
|
||||
; Put the first argument into the return value
|
||||
; Restore the thread information block:
|
||||
pop gs:[0x10]
|
||||
pop gs:[0x08]
|
||||
pop gs:[0x00]
|
||||
|
||||
; Put the first argument into the return value:
|
||||
mov rax, rcx
|
||||
|
||||
; We pop the return address and jump to it
|
||||
; We pop the return address and jump to it:
|
||||
ret
|
||||
coroutine_transfer endp
|
||||
|
||||
|
|
|
@ -40,9 +40,10 @@ static inline void coroutine_initialize(
|
|||
}
|
||||
|
||||
/* Windows Thread Information Block */
|
||||
*--context->stack_pointer = 0;
|
||||
*--context->stack_pointer = stack_pointer;
|
||||
*--context->stack_pointer = (void*)stack_size;
|
||||
*--context->stack_pointer = 0; /* gs:[0x00] */
|
||||
*--context->stack_pointer = stack_pointer + stack_size; /* gs:[0x08] */
|
||||
*--context->stack_pointer = (void*)stack_pointer; /* gs:[0x10] */
|
||||
|
||||
|
||||
*--context->stack_pointer = (void*)start;
|
||||
|
||||
|
|
Loading…
Reference in a new issue