mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
parent
ba337577a8
commit
c276c16b66
112 changed files with 7048 additions and 9 deletions
|
@ -135,6 +135,7 @@ locations.
|
|||
├─ .git/ # Git configuration and source directory
|
||||
├─ TSRM/ # Thread Safe Resource Manager
|
||||
└─ Zend/ # Zend Engine
|
||||
├─ asm/ # Bundled from src/asm in https://github.com/boostorg/context
|
||||
├─ zend_vm_execute.h # Generated by `Zend/zend_vm_gen.php`
|
||||
├─ zend_vm_opcodes.c # Generated by `Zend/zend_vm_gen.php`
|
||||
├─ zend_vm_opcodes.h # Generated by `Zend/zend_vm_gen.php`
|
||||
|
|
|
@ -153,6 +153,8 @@ PHP 8.1 UPGRADE NOTES
|
|||
RFC: https://wiki.php.net/rfc/enumerations
|
||||
. Added support for never return type
|
||||
RFC: https://wiki.php.net/rfc/noreturn_type
|
||||
. Added support for fibers.
|
||||
RFC: https://wiki.php.net/rfc/fibers
|
||||
|
||||
- Curl:
|
||||
. Added CURLOPT_DOH_URL option.
|
||||
|
|
23
Zend/asm/LICENSE
Normal file
23
Zend/asm/LICENSE
Normal file
|
@ -0,0 +1,23 @@
|
|||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
114
Zend/asm/jump_arm64_aapcs_elf_gas.S
Normal file
114
Zend/asm/jump_arm64_aapcs_elf_gas.S
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
Copyright Edward Nevill + Oliver Kowalke 2015
|
||||
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)
|
||||
*/
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d8 | d9 | d10 | d11 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d12 | d13 | d14 | d15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x19 | x20 | x21 | x22 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x23 | x24 | x25 | x26 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x27 | x28 | FP | LR | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | | | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0xa0| 0xa4| 0xa8| 0xac| | | *
|
||||
* ------------------------------------------------- *
|
||||
* | PC | align | | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "jump_arm64_aapcs_elf_gas.S"
|
||||
.text
|
||||
.align 2
|
||||
.global jump_fcontext
|
||||
.type jump_fcontext, %function
|
||||
jump_fcontext:
|
||||
# prepare stack for GP + FPU
|
||||
sub sp, sp, #0xb0
|
||||
|
||||
# save d8 - d15
|
||||
stp d8, d9, [sp, #0x00]
|
||||
stp d10, d11, [sp, #0x10]
|
||||
stp d12, d13, [sp, #0x20]
|
||||
stp d14, d15, [sp, #0x30]
|
||||
|
||||
# save x19-x30
|
||||
stp x19, x20, [sp, #0x40]
|
||||
stp x21, x22, [sp, #0x50]
|
||||
stp x23, x24, [sp, #0x60]
|
||||
stp x25, x26, [sp, #0x70]
|
||||
stp x27, x28, [sp, #0x80]
|
||||
stp x29, x30, [sp, #0x90]
|
||||
|
||||
# save LR as PC
|
||||
str x30, [sp, #0xa0]
|
||||
|
||||
# store RSP (pointing to context-data) in X0
|
||||
mov x4, sp
|
||||
|
||||
# restore RSP (pointing to context-data) from X1
|
||||
mov sp, x0
|
||||
|
||||
# load d8 - d15
|
||||
ldp d8, d9, [sp, #0x00]
|
||||
ldp d10, d11, [sp, #0x10]
|
||||
ldp d12, d13, [sp, #0x20]
|
||||
ldp d14, d15, [sp, #0x30]
|
||||
|
||||
# load x19-x30
|
||||
ldp x19, x20, [sp, #0x40]
|
||||
ldp x21, x22, [sp, #0x50]
|
||||
ldp x23, x24, [sp, #0x60]
|
||||
ldp x25, x26, [sp, #0x70]
|
||||
ldp x27, x28, [sp, #0x80]
|
||||
ldp x29, x30, [sp, #0x90]
|
||||
|
||||
# return transfer_t from jump
|
||||
# pass transfer_t as first arg in context function
|
||||
# X0 == FCTX, X1 == DATA
|
||||
mov x0, x4
|
||||
|
||||
# load pc
|
||||
ldr x4, [sp, #0xa0]
|
||||
|
||||
# restore stack from GP + FPU
|
||||
add sp, sp, #0xb0
|
||||
|
||||
ret x4
|
||||
.size jump_fcontext,.-jump_fcontext
|
||||
# Mark that we don't need executable stack.
|
||||
.section .note.GNU-stack,"",%progbits
|
109
Zend/asm/jump_arm64_aapcs_macho_gas.S
Normal file
109
Zend/asm/jump_arm64_aapcs_macho_gas.S
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Copyright Edward Nevill + Oliver Kowalke 2015
|
||||
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)
|
||||
*/
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d8 | d9 | d10 | d11 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d12 | d13 | d14 | d15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x19 | x20 | x21 | x22 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x23 | x24 | x25 | x26 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x27 | x28 | FP | LR | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | | | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0xa0| 0xa4| 0xa8| 0xac| | | *
|
||||
* ------------------------------------------------- *
|
||||
* | PC | align | | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _jump_fcontext
|
||||
.balign 16
|
||||
_jump_fcontext:
|
||||
; prepare stack for GP + FPU
|
||||
sub sp, sp, #0xb0
|
||||
|
||||
; save d8 - d15
|
||||
stp d8, d9, [sp, #0x00]
|
||||
stp d10, d11, [sp, #0x10]
|
||||
stp d12, d13, [sp, #0x20]
|
||||
stp d14, d15, [sp, #0x30]
|
||||
|
||||
; save x19-x30
|
||||
stp x19, x20, [sp, #0x40]
|
||||
stp x21, x22, [sp, #0x50]
|
||||
stp x23, x24, [sp, #0x60]
|
||||
stp x25, x26, [sp, #0x70]
|
||||
stp x27, x28, [sp, #0x80]
|
||||
stp fp, lr, [sp, #0x90]
|
||||
|
||||
; save LR as PC
|
||||
str lr, [sp, #0xa0]
|
||||
|
||||
; store RSP (pointing to context-data) in X0
|
||||
mov x4, sp
|
||||
|
||||
; restore RSP (pointing to context-data) from X1
|
||||
mov sp, x0
|
||||
|
||||
; load d8 - d15
|
||||
ldp d8, d9, [sp, #0x00]
|
||||
ldp d10, d11, [sp, #0x10]
|
||||
ldp d12, d13, [sp, #0x20]
|
||||
ldp d14, d15, [sp, #0x30]
|
||||
|
||||
; load x19-x30
|
||||
ldp x19, x20, [sp, #0x40]
|
||||
ldp x21, x22, [sp, #0x50]
|
||||
ldp x23, x24, [sp, #0x60]
|
||||
ldp x25, x26, [sp, #0x70]
|
||||
ldp x27, x28, [sp, #0x80]
|
||||
ldp fp, lr, [sp, #0x90]
|
||||
|
||||
; return transfer_t from jump
|
||||
; pass transfer_t as first arg in context function
|
||||
; X0 == FCTX, X1 == DATA
|
||||
mov x0, x4
|
||||
|
||||
; load pc
|
||||
ldr x4, [sp, #0xa0]
|
||||
|
||||
; restore stack from GP + FPU
|
||||
add sp, sp, #0xb0
|
||||
|
||||
ret x4
|
88
Zend/asm/jump_arm_aapcs_elf_gas.S
Normal file
88
Zend/asm/jump_arm_aapcs_elf_gas.S
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
|
||||
* ------------------------------------------------- *
|
||||
* |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
|
||||
* ------------------------------------------------- *
|
||||
* | v8 | lr | pc | FCTX| DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "jump_arm_aapcs_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,%function
|
||||
.syntax unified
|
||||
jump_fcontext:
|
||||
@ save LR as PC
|
||||
push {lr}
|
||||
@ save hidden,V1-V8,LR
|
||||
push {a1,v1-v8,lr}
|
||||
|
||||
@ prepare stack for FPU
|
||||
sub sp, sp, #64
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@ save S16-S31
|
||||
vstmia sp, {d8-d15}
|
||||
#endif
|
||||
|
||||
@ store RSP (pointing to context-data) in A1
|
||||
mov a1, sp
|
||||
|
||||
@ restore RSP (pointing to context-data) from A2
|
||||
mov sp, a2
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@ restore S16-S31
|
||||
vldmia sp, {d8-d15}
|
||||
#endif
|
||||
@ prepare stack for FPU
|
||||
add sp, sp, #64
|
||||
|
||||
@ restore hidden,V1-V8,LR
|
||||
pop {a4,v1-v8,lr}
|
||||
|
||||
@ return transfer_t from jump
|
||||
str a1, [a4, #0]
|
||||
str a3, [a4, #4]
|
||||
@ pass transfer_t as first arg in context function
|
||||
@ A1 == FCTX, A2 == DATA
|
||||
mov a2, a3
|
||||
|
||||
@ restore PC
|
||||
pop {pc}
|
||||
.size jump_fcontext,.-jump_fcontext
|
||||
|
||||
@ Mark that we don't need executable stack.
|
||||
.section .note.GNU-stack,"",%progbits
|
95
Zend/asm/jump_arm_aapcs_macho_gas.S
Normal file
95
Zend/asm/jump_arm_aapcs_macho_gas.S
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | sjlj|hiddn| v1 | v2 | v3 | v4 | v5 | v6 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | v7 | v8 | lr | pc | FCTX| DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _jump_fcontext
|
||||
.align 2
|
||||
_jump_fcontext:
|
||||
@ save LR as PC
|
||||
push {lr}
|
||||
@ save hidden,V1-V8,LR
|
||||
push {a1,v1-v8,lr}
|
||||
|
||||
@ locate TLS to save/restore SjLj handler
|
||||
mrc p15, 0, v2, c13, c0, #3
|
||||
bic v2, v2, #3
|
||||
|
||||
@ load TLS[__PTK_LIBC_DYLD_Unwind_SjLj_Key]
|
||||
ldr v1, [v2, #8]
|
||||
@ save SjLj handler
|
||||
push {v1}
|
||||
|
||||
@ prepare stack for FPU
|
||||
sub sp, sp, #64
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@ save S16-S31
|
||||
vstmia sp, {d8-d15}
|
||||
#endif
|
||||
|
||||
@ store RSP (pointing to context-data) in A1
|
||||
mov a1, sp
|
||||
|
||||
@ restore RSP (pointing to context-data) from A2
|
||||
mov sp, a2
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@ restore S16-S31
|
||||
vldmia sp, {d8-d15}
|
||||
#endif
|
||||
@ prepare stack for FPU
|
||||
add sp, sp, #64
|
||||
|
||||
@ r#estore SjLj handler
|
||||
pop {v1}
|
||||
@ store SjLj handler in TLS
|
||||
str v1, [v2, #8]
|
||||
|
||||
@ restore hidden,V1-V8,LR
|
||||
pop {a4,v1-v8,lr}
|
||||
|
||||
@ return transfer_t from jump
|
||||
str a1, [a4, #0]
|
||||
str a3, [a4, #4]
|
||||
@ pass transfer_t as first arg in context function
|
||||
@ A1 == FCTX, A2 == DATA
|
||||
mov a2, a3
|
||||
|
||||
@ restore PC
|
||||
pop {pc}
|
24
Zend/asm/jump_combined_sysv_macho_gas.S
Normal file
24
Zend/asm/jump_combined_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright Sergue E. Leontiev 2013.
|
||||
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)
|
||||
*/
|
||||
|
||||
// Stub file for universal binary
|
||||
|
||||
#if defined(__i386__)
|
||||
#include "jump_i386_sysv_macho_gas.S"
|
||||
#elif defined(__x86_64__)
|
||||
#include "jump_x86_64_sysv_macho_gas.S"
|
||||
#elif defined(__ppc__)
|
||||
#include "jump_ppc32_sysv_macho_gas.S"
|
||||
#elif defined(__ppc64__)
|
||||
#include "jump_ppc64_sysv_macho_gas.S"
|
||||
#elif defined(__arm__)
|
||||
#include "jump_arm_aapcs_macho_gas.S"
|
||||
#elif defined(__arm64__)
|
||||
#include "jump_arm64_aapcs_macho_gas.S"
|
||||
#else
|
||||
#error "No arch's"
|
||||
#endif
|
116
Zend/asm/jump_i386_ms_pe_masm.asm
Normal file
116
Zend/asm/jump_i386_ms_pe_masm.asm
Normal file
|
@ -0,0 +1,116 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; 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)
|
||||
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | ESI | EBX | EBP | EIP | to | data | EH NXT |SEH HNDLR|
|
||||
; ---------------------------------------------------------------------------------
|
||||
|
||||
.386
|
||||
.XMM
|
||||
.model flat, c
|
||||
.code
|
||||
|
||||
jump_fcontext PROC BOOST_CONTEXT_EXPORT
|
||||
; prepare stack
|
||||
lea esp, [esp-02ch]
|
||||
|
||||
IFNDEF BOOST_USE_TSX
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [esp]
|
||||
; save x87 control-word
|
||||
fnstcw [esp+04h]
|
||||
ENDIF
|
||||
|
||||
assume fs:nothing
|
||||
; load NT_TIB into ECX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
; load fiber local storage
|
||||
mov eax, [edx+010h]
|
||||
mov [esp+08h], eax
|
||||
; load current deallocation stack
|
||||
mov eax, [edx+0e0ch]
|
||||
mov [esp+0ch], eax
|
||||
; load current stack limit
|
||||
mov eax, [edx+08h]
|
||||
mov [esp+010h], eax
|
||||
; load current stack base
|
||||
mov eax, [edx+04h]
|
||||
mov [esp+014h], eax
|
||||
; load current SEH exception list
|
||||
mov eax, [edx]
|
||||
mov [esp+018h], eax
|
||||
|
||||
mov [esp+01ch], edi ; save EDI
|
||||
mov [esp+020h], esi ; save ESI
|
||||
mov [esp+024h], ebx ; save EBX
|
||||
mov [esp+028h], ebp ; save EBP
|
||||
|
||||
; store ESP (pointing to context-data) in EAX
|
||||
mov eax, esp
|
||||
|
||||
; firstarg of jump_fcontext() == fcontext to jump to
|
||||
mov ecx, [esp+030h]
|
||||
|
||||
; restore ESP (pointing to context-data) from ECX
|
||||
mov esp, ecx
|
||||
|
||||
IFNDEF BOOST_USE_TSX
|
||||
; restore MMX control- and status-word
|
||||
ldmxcsr [esp]
|
||||
; restore x87 control-word
|
||||
fldcw [esp+04h]
|
||||
ENDIF
|
||||
|
||||
assume fs:nothing
|
||||
; load NT_TIB into EDX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
; restore fiber local storage
|
||||
mov ecx, [esp+08h]
|
||||
mov [edx+010h], ecx
|
||||
; restore current deallocation stack
|
||||
mov ecx, [esp+0ch]
|
||||
mov [edx+0e0ch], ecx
|
||||
; restore current stack limit
|
||||
mov ecx, [esp+010h]
|
||||
mov [edx+08h], ecx
|
||||
; restore current stack base
|
||||
mov ecx, [esp+014h]
|
||||
mov [edx+04h], ecx
|
||||
; restore current SEH exception list
|
||||
mov ecx, [esp+018h]
|
||||
mov [edx], ecx
|
||||
|
||||
mov ecx, [esp+02ch] ; restore EIP
|
||||
|
||||
mov edi, [esp+01ch] ; restore EDI
|
||||
mov esi, [esp+020h] ; restore ESI
|
||||
mov ebx, [esp+024h] ; restore EBX
|
||||
mov ebp, [esp+028h] ; restore EBP
|
||||
|
||||
; prepare stack
|
||||
lea esp, [esp+030h]
|
||||
|
||||
; return transfer_t
|
||||
; FCTX == EAX, DATA == EDX
|
||||
mov edx, [eax+034h]
|
||||
|
||||
; jump to context
|
||||
jmp ecx
|
||||
jump_fcontext ENDP
|
||||
END
|
83
Zend/asm/jump_i386_sysv_elf_gas.S
Normal file
83
Zend/asm/jump_i386_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | to | data | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.file "jump_i386_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,@function
|
||||
jump_fcontext:
|
||||
leal -0x18(%esp), %esp /* prepare stack */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
stmxcsr (%esp) /* save MMX control- and status-word */
|
||||
fnstcw 0x4(%esp) /* save x87 control-word */
|
||||
#endif
|
||||
|
||||
movl %edi, 0x8(%esp) /* save EDI */
|
||||
movl %esi, 0xc(%esp) /* save ESI */
|
||||
movl %ebx, 0x10(%esp) /* save EBX */
|
||||
movl %ebp, 0x14(%esp) /* save EBP */
|
||||
|
||||
/* store ESP (pointing to context-data) in ECX */
|
||||
movl %esp, %ecx
|
||||
|
||||
/* first arg of jump_fcontext() == fcontext to jump to */
|
||||
movl 0x20(%esp), %eax
|
||||
|
||||
/* second arg of jump_fcontext() == data to be transferred */
|
||||
movl 0x24(%esp), %edx
|
||||
|
||||
/* restore ESP (pointing to context-data) from EAX */
|
||||
movl %eax, %esp
|
||||
|
||||
/* address of returned transport_t */
|
||||
movl 0x1c(%esp), %eax
|
||||
/* return parent fcontext_t */
|
||||
movl %ecx, (%eax)
|
||||
/* return data */
|
||||
movl %edx, 0x4(%eax)
|
||||
|
||||
movl 0x18(%esp), %ecx /* restore EIP */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
ldmxcsr (%esp) /* restore MMX control- and status-word */
|
||||
fldcw 0x4(%esp) /* restore x87 control-word */
|
||||
#endif
|
||||
|
||||
movl 0x8(%esp), %edi /* restore EDI */
|
||||
movl 0xc(%esp), %esi /* restore ESI */
|
||||
movl 0x10(%esp), %ebx /* restore EBX */
|
||||
movl 0x14(%esp), %ebp /* restore EBP */
|
||||
|
||||
leal 0x20(%esp), %esp /* prepare stack */
|
||||
|
||||
/* jump to context */
|
||||
jmp *%ecx
|
||||
.size jump_fcontext,.-jump_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
74
Zend/asm/jump_i386_sysv_macho_gas.S
Normal file
74
Zend/asm/jump_i386_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | to | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | data | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl _jump_fcontext
|
||||
.align 2
|
||||
_jump_fcontext:
|
||||
leal -0x18(%esp), %esp /* prepare stack */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
stmxcsr (%esp) /* save MMX control- and status-word */
|
||||
fnstcw 0x4(%esp) /* save x87 control-word */
|
||||
#endif
|
||||
|
||||
movl %edi, 0x8(%esp) /* save EDI */
|
||||
movl %esi, 0xc(%esp) /* save ESI */
|
||||
movl %ebx, 0x10(%esp) /* save EBX */
|
||||
movl %ebp, 0x14(%esp) /* save EBP */
|
||||
|
||||
/* store ESP (pointing to context-data) in ECX */
|
||||
movl %esp, %ecx
|
||||
|
||||
/* first arg of jump_fcontext() == fcontext to jump to */
|
||||
movl 0x1c(%esp), %eax
|
||||
|
||||
/* second arg of jump_fcontext() == data to be transferred */
|
||||
movl 0x20(%esp), %edx
|
||||
|
||||
/* restore ESP (pointing to context-data) from EAX */
|
||||
movl %eax, %esp
|
||||
|
||||
/* return parent fcontext_t */
|
||||
movl %ecx, %eax
|
||||
/* returned data is stored in EDX */
|
||||
|
||||
movl 0x18(%esp), %ecx /* restore EIP */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
ldmxcsr (%esp) /* restore MMX control- and status-word */
|
||||
fldcw 0x4(%esp) /* restore x87 control-word */
|
||||
#endif
|
||||
|
||||
movl 0x8(%esp), %edi /* restore EDI */
|
||||
movl 0xc(%esp), %esi /* restore ESI */
|
||||
movl 0x10(%esp), %ebx /* restore EBX */
|
||||
movl 0x14(%esp), %ebp /* restore EBP */
|
||||
|
||||
leal 0x1c(%esp), %esp /* prepare stack */
|
||||
|
||||
/* jump to context */
|
||||
jmp *%ecx
|
119
Zend/asm/jump_mips32_o32_elf_gas.S
Normal file
119
Zend/asm/jump_mips32_o32_elf_gas.S
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F20 | F22 | F24 | F26 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F28 | F30 | S0 | S1 | S2 | S3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S4 | S5 | S6 | S7 | FP |hiddn| RA | PC | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | ABI ARGS | GP | FCTX| DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************/
|
||||
|
||||
.file "jump_mips32_o32_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,@function
|
||||
.ent jump_fcontext
|
||||
jump_fcontext:
|
||||
# reserve space on stack
|
||||
addiu $sp, $sp, -96
|
||||
|
||||
sw $s0, 48($sp) # save S0
|
||||
sw $s1, 52($sp) # save S1
|
||||
sw $s2, 56($sp) # save S2
|
||||
sw $s3, 60($sp) # save S3
|
||||
sw $s4, 64($sp) # save S4
|
||||
sw $s5, 68($sp) # save S5
|
||||
sw $s6, 72($sp) # save S6
|
||||
sw $s7, 76($sp) # save S7
|
||||
sw $fp, 80($sp) # save FP
|
||||
sw $a0, 84($sp) # save hidden, address of returned transfer_t
|
||||
sw $ra, 88($sp) # save RA
|
||||
sw $ra, 92($sp) # save RA as PC
|
||||
|
||||
#if defined(__mips_hard_float)
|
||||
s.d $f20, ($sp) # save F20
|
||||
s.d $f22, 8($sp) # save F22
|
||||
s.d $f24, 16($sp) # save F24
|
||||
s.d $f26, 24($sp) # save F26
|
||||
s.d $f28, 32($sp) # save F28
|
||||
s.d $f30, 40($sp) # save F30
|
||||
#endif
|
||||
|
||||
# store SP (pointing to context-data) in A0
|
||||
move $a0, $sp
|
||||
|
||||
# restore SP (pointing to context-data) from A1
|
||||
move $sp, $a1
|
||||
|
||||
#if defined(__mips_hard_float)
|
||||
l.d $f20, ($sp) # restore F20
|
||||
l.d $f22, 8($sp) # restore F22
|
||||
l.d $f24, 16($sp) # restore F24
|
||||
l.d $f26, 24($sp) # restore F26
|
||||
l.d $f28, 32($sp) # restore F28
|
||||
l.d $f30, 40($sp) # restore F30
|
||||
#endif
|
||||
|
||||
lw $s0, 48($sp) # restore S0
|
||||
lw $s1, 52($sp) # restore S1
|
||||
lw $s2, 56($sp) # restore S2
|
||||
lw $s3, 60($sp) # restore S3
|
||||
lw $s4, 64($sp) # restore S4
|
||||
lw $s5, 68($sp) # restore S5
|
||||
lw $s6, 72($sp) # restore S6
|
||||
lw $s7, 76($sp) # restore S7
|
||||
lw $fp, 80($sp) # restore FP
|
||||
lw $v0, 84($sp) # restore hidden, address of returned transfer_t
|
||||
lw $ra, 88($sp) # restore RA
|
||||
|
||||
# load PC
|
||||
lw $t9, 92($sp)
|
||||
|
||||
# adjust stack
|
||||
addiu $sp, $sp, 96
|
||||
|
||||
# return transfer_t from jump
|
||||
sw $a0, ($v0) # fctx of transfer_t
|
||||
sw $a2, 4($v0) # data of transfer_t
|
||||
# pass transfer_t as first arg in context function
|
||||
# A0 == fctx, A1 == data
|
||||
move $a1, $a2
|
||||
|
||||
# jump to context
|
||||
jr $t9
|
||||
.end jump_fcontext
|
||||
.size jump_fcontext, .-jump_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
124
Zend/asm/jump_mips64_n64_elf_gas.S
Normal file
124
Zend/asm/jump_mips64_n64_elf_gas.S
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright Jiaxun Yang 2018.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 8 | 16 | 24 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F24 | F25 | F26 | F27 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 40 | 48 | 56 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F28 | F29 | F30 | F31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 72 | 80 | 88 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S0 | S1 | S2 | S3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S4 | S5 | S6 | S7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | FP | GP | RA | PC | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************/
|
||||
|
||||
.file "jump_mips64_n64_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 3
|
||||
.type jump_fcontext,@function
|
||||
.ent jump_fcontext
|
||||
jump_fcontext:
|
||||
# reserve space on stack
|
||||
daddiu $sp, $sp, -160
|
||||
|
||||
sd $s0, 64($sp) # save S0
|
||||
sd $s1, 72($sp) # save S1
|
||||
sd $s2, 80($sp) # save S2
|
||||
sd $s3, 88($sp) # save S3
|
||||
sd $s4, 96($sp) # save S4
|
||||
sd $s5, 104($sp) # save S5
|
||||
sd $s6, 112($sp) # save S6
|
||||
sd $s7, 120($sp) # save S7
|
||||
sd $fp, 128($sp) # save FP
|
||||
sd $ra, 144($sp) # save RA
|
||||
sd $ra, 152($sp) # save RA as PC
|
||||
|
||||
#if defined(__mips_hard_float)
|
||||
s.d $f24, 0($sp) # save F24
|
||||
s.d $f25, 8($sp) # save F25
|
||||
s.d $f26, 16($sp) # save F26
|
||||
s.d $f27, 24($sp) # save F27
|
||||
s.d $f28, 32($sp) # save F28
|
||||
s.d $f29, 40($sp) # save F29
|
||||
s.d $f30, 48($sp) # save F30
|
||||
s.d $f31, 56($sp) # save F31
|
||||
#endif
|
||||
|
||||
# store SP (pointing to old context-data) in v0 as return
|
||||
move $v0, $sp
|
||||
|
||||
# get SP (pointing to new context-data) from a0 param
|
||||
move $sp, $a0
|
||||
|
||||
#if defined(__mips_hard_float)
|
||||
l.d $f24, 0($sp) # restore F24
|
||||
l.d $f25, 8($sp) # restore F25
|
||||
l.d $f26, 16($sp) # restore F26
|
||||
l.d $f27, 24($sp) # restore F27
|
||||
l.d $f28, 32($sp) # restore F28
|
||||
l.d $f29, 40($sp) # restore F29
|
||||
l.d $f30, 48($sp) # restore F30
|
||||
l.d $f31, 56($sp) # restore F31
|
||||
#endif
|
||||
|
||||
ld $s0, 64($sp) # restore S0
|
||||
ld $s1, 72($sp) # restore S1
|
||||
ld $s2, 80($sp) # restore S2
|
||||
ld $s3, 88($sp) # restore S3
|
||||
ld $s4, 96($sp) # restore S4
|
||||
ld $s5, 104($sp) # restore S5
|
||||
ld $s6, 112($sp) # restore S6
|
||||
ld $s7, 120($sp) # restore S7
|
||||
ld $fp, 128($sp) # restore FP
|
||||
ld $ra, 144($sp) # restore RAa
|
||||
|
||||
# load PC
|
||||
ld $t9, 152($sp)
|
||||
|
||||
# adjust stack
|
||||
daddiu $sp, $sp, 160
|
||||
|
||||
move $a0, $v0 # move old sp from v0 to a0 as param
|
||||
move $v1, $a1 # move *data from a1 to v1 as return
|
||||
|
||||
# jump to context
|
||||
jr $t9
|
||||
.end jump_fcontext
|
||||
.size jump_fcontext, .-jump_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
201
Zend/asm/jump_ppc32_sysv_elf_gas.S
Normal file
201
Zend/asm/jump_ppc32_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* |bchai|hiddn| fpscr | PC | CR | R14 | R15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R16 | R17 | R18 | R19 | R20 | R21 | R22 | R23 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F14 | F15 | F16 | F17 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F18 | F19 | F20 | F21 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F22 | F23 | F24 | F25 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F26 | F27 | F28 | F29 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------|------------ *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | *
|
||||
* ------------------------|------------ *
|
||||
* | F30 | F31 |bchai| LR | *
|
||||
* ------------------------|------------ *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "jump_ppc32_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,@function
|
||||
jump_fcontext:
|
||||
# Linux: jump_fcontext( hidden transfer_t * R3, R4, R5)
|
||||
# Other: transfer_t R3:R4 = jump_fcontext( R3, R4)
|
||||
|
||||
mflr %r0 # return address from LR
|
||||
mffs %f0 # FPSCR
|
||||
mfcr %r8 # condition register
|
||||
|
||||
stwu %r1, -240(%r1) # allocate stack space, R1 % 16 == 0
|
||||
stw %r0, 244(%r1) # save LR in caller's frame
|
||||
|
||||
#ifdef __linux__
|
||||
stw %r3, 4(%r1) # hidden pointer
|
||||
#endif
|
||||
|
||||
stfd %f0, 8(%r1) # FPSCR
|
||||
stw %r0, 16(%r1) # LR as PC
|
||||
stw %r8, 20(%r1) # CR
|
||||
|
||||
# Save registers R14 to R31.
|
||||
# Don't change R2, the thread-local storage pointer.
|
||||
# Don't change R13, the small data pointer.
|
||||
stw %r14, 24(%r1)
|
||||
stw %r15, 28(%r1)
|
||||
stw %r16, 32(%r1)
|
||||
stw %r17, 36(%r1)
|
||||
stw %r18, 40(%r1)
|
||||
stw %r19, 44(%r1)
|
||||
stw %r20, 48(%r1)
|
||||
stw %r21, 52(%r1)
|
||||
stw %r22, 56(%r1)
|
||||
stw %r23, 60(%r1)
|
||||
stw %r24, 64(%r1)
|
||||
stw %r25, 68(%r1)
|
||||
stw %r26, 72(%r1)
|
||||
stw %r27, 76(%r1)
|
||||
stw %r28, 80(%r1)
|
||||
stw %r29, 84(%r1)
|
||||
stw %r30, 88(%r1)
|
||||
stw %r31, 92(%r1)
|
||||
|
||||
# Save registers F14 to F31 in slots with 8-byte alignment.
|
||||
# 4-byte alignment may stall the pipeline of some processors.
|
||||
# Less than 4 may cause alignment traps.
|
||||
stfd %f14, 96(%r1)
|
||||
stfd %f15, 104(%r1)
|
||||
stfd %f16, 112(%r1)
|
||||
stfd %f17, 120(%r1)
|
||||
stfd %f18, 128(%r1)
|
||||
stfd %f19, 136(%r1)
|
||||
stfd %f20, 144(%r1)
|
||||
stfd %f21, 152(%r1)
|
||||
stfd %f22, 160(%r1)
|
||||
stfd %f23, 168(%r1)
|
||||
stfd %f24, 176(%r1)
|
||||
stfd %f25, 184(%r1)
|
||||
stfd %f26, 192(%r1)
|
||||
stfd %f27, 200(%r1)
|
||||
stfd %f28, 208(%r1)
|
||||
stfd %f29, 216(%r1)
|
||||
stfd %f30, 224(%r1)
|
||||
stfd %f31, 232(%r1)
|
||||
|
||||
# store RSP (pointing to context-data) in R7/R6
|
||||
# restore RSP (pointing to context-data) from R4/R3
|
||||
#ifdef __linux__
|
||||
mr %r7, %r1
|
||||
mr %r1, %r4
|
||||
lwz %r3, 4(%r1) # hidden pointer
|
||||
#else
|
||||
mr %r6, %r1
|
||||
mr %r1, %r3
|
||||
#endif
|
||||
|
||||
lfd %f0, 8(%r1) # FPSCR
|
||||
lwz %r0, 16(%r1) # PC
|
||||
lwz %r8, 20(%r1) # CR
|
||||
|
||||
mtfsf 0xff, %f0 # restore FPSCR
|
||||
mtctr %r0 # load CTR with PC
|
||||
mtcr %r8 # restore CR
|
||||
|
||||
# restore R14 to R31
|
||||
lwz %r14, 24(%r1)
|
||||
lwz %r15, 28(%r1)
|
||||
lwz %r16, 32(%r1)
|
||||
lwz %r17, 36(%r1)
|
||||
lwz %r18, 40(%r1)
|
||||
lwz %r19, 44(%r1)
|
||||
lwz %r20, 48(%r1)
|
||||
lwz %r21, 52(%r1)
|
||||
lwz %r22, 56(%r1)
|
||||
lwz %r23, 60(%r1)
|
||||
lwz %r24, 64(%r1)
|
||||
lwz %r25, 68(%r1)
|
||||
lwz %r26, 72(%r1)
|
||||
lwz %r27, 76(%r1)
|
||||
lwz %r28, 80(%r1)
|
||||
lwz %r29, 84(%r1)
|
||||
lwz %r30, 88(%r1)
|
||||
lwz %r31, 92(%r1)
|
||||
|
||||
# restore F14 to F31
|
||||
lfd %f14, 96(%r1)
|
||||
lfd %f15, 104(%r1)
|
||||
lfd %f16, 112(%r1)
|
||||
lfd %f17, 120(%r1)
|
||||
lfd %f18, 128(%r1)
|
||||
lfd %f19, 136(%r1)
|
||||
lfd %f20, 144(%r1)
|
||||
lfd %f21, 152(%r1)
|
||||
lfd %f22, 160(%r1)
|
||||
lfd %f23, 168(%r1)
|
||||
lfd %f24, 176(%r1)
|
||||
lfd %f25, 184(%r1)
|
||||
lfd %f26, 192(%r1)
|
||||
lfd %f27, 200(%r1)
|
||||
lfd %f28, 208(%r1)
|
||||
lfd %f29, 216(%r1)
|
||||
lfd %f30, 224(%r1)
|
||||
lfd %f31, 232(%r1)
|
||||
|
||||
# restore LR from caller's frame
|
||||
lwz %r0, 244(%r1)
|
||||
mtlr %r0
|
||||
|
||||
# adjust stack
|
||||
addi %r1, %r1, 240
|
||||
|
||||
# return transfer_t
|
||||
#ifdef __linux__
|
||||
stw %r7, 0(%r3)
|
||||
stw %r5, 4(%r3)
|
||||
#else
|
||||
mr %r3, %r6
|
||||
# %r4, %r4
|
||||
#endif
|
||||
|
||||
# jump to context
|
||||
bctr
|
||||
.size jump_fcontext, .-jump_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
201
Zend/asm/jump_ppc32_sysv_macho_gas.S
Normal file
201
Zend/asm/jump_ppc32_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F14 | F15 | F16 | F17 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F18 | F19 | F20 | F21 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F22 | F23 | F24 | F25 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F26 | F27 | F28 | F29 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F30 | F31 | fpscr | R13 | R14 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R31 |hiddn| CR | LR | PC |bchai|linkr| FCTX| *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | | *
|
||||
* ------------------------------------------------- *
|
||||
* | 256 | | *
|
||||
* ------------------------------------------------- *
|
||||
* | DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _jump_fcontext
|
||||
.align 2
|
||||
_jump_fcontext:
|
||||
; reserve space on stack
|
||||
subi r1, r1, 244
|
||||
|
||||
stfd f14, 0(r1) # save F14
|
||||
stfd f15, 8(r1) # save F15
|
||||
stfd f16, 16(r1) # save F16
|
||||
stfd f17, 24(r1) # save F17
|
||||
stfd f18, 32(r1) # save F18
|
||||
stfd f19, 40(r1) # save F19
|
||||
stfd f20, 48(r1) # save F20
|
||||
stfd f21, 56(r1) # save F21
|
||||
stfd f22, 64(r1) # save F22
|
||||
stfd f23, 72(r1) # save F23
|
||||
stfd f24, 80(r1) # save F24
|
||||
stfd f25, 88(r1) # save F25
|
||||
stfd f26, 96(r1) # save F26
|
||||
stfd f27, 104(r1) # save F27
|
||||
stfd f28, 112(r1) # save F28
|
||||
stfd f29, 120(r1) # save F29
|
||||
stfd f30, 128(r1) # save F30
|
||||
stfd f31, 136(r1) # save F31
|
||||
mffs f0 # load FPSCR
|
||||
stfd f0, 144(r1) # save FPSCR
|
||||
|
||||
stw r13, 152(r1) # save R13
|
||||
stw r14, 156(r1) # save R14
|
||||
stw r15, 160(r1) # save R15
|
||||
stw r16, 164(r1) # save R16
|
||||
stw r17, 168(r1) # save R17
|
||||
stw r18, 172(r1) # save R18
|
||||
stw r19, 176(r1) # save R19
|
||||
stw r20, 180(r1) # save R20
|
||||
stw r21, 184(r1) # save R21
|
||||
stw r22, 188(r1) # save R22
|
||||
stw r23, 192(r1) # save R23
|
||||
stw r24, 196(r1) # save R24
|
||||
stw r25, 200(r1) # save R25
|
||||
stw r26, 204(r1) # save R26
|
||||
stw r27, 208(r1) # save R27
|
||||
stw r28, 212(r1) # save R28
|
||||
stw r29, 216(r1) # save R29
|
||||
stw r30, 220(r1) # save R30
|
||||
stw r31, 224(r1) # save R31
|
||||
stw r3, 228(r1) # save hidden
|
||||
|
||||
# save CR
|
||||
mfcr r0
|
||||
stw r0, 232(r1)
|
||||
# save LR
|
||||
mflr r0
|
||||
stw r0, 236(r1)
|
||||
# save LR as PC
|
||||
stw r0, 240(r1)
|
||||
|
||||
# store RSP (pointing to context-data) in R6
|
||||
mr r6, r1
|
||||
|
||||
# restore RSP (pointing to context-data) from R4
|
||||
mr r1, r4
|
||||
|
||||
lfd f14, 0(r1) # restore F14
|
||||
lfd f15, 8(r1) # restore F15
|
||||
lfd f16, 16(r1) # restore F16
|
||||
lfd f17, 24(r1) # restore F17
|
||||
lfd f18, 32(r1) # restore F18
|
||||
lfd f19, 40(r1) # restore F19
|
||||
lfd f20, 48(r1) # restore F20
|
||||
lfd f21, 56(r1) # restore F21
|
||||
lfd f22, 64(r1) # restore F22
|
||||
lfd f23, 72(r1) # restore F23
|
||||
lfd f24, 80(r1) # restore F24
|
||||
lfd f25, 88(r1) # restore F25
|
||||
lfd f26, 96(r1) # restore F26
|
||||
lfd f27, 104(r1) # restore F27
|
||||
lfd f28, 112(r1) # restore F28
|
||||
lfd f29, 120(r1) # restore F29
|
||||
lfd f30, 128(r1) # restore F30
|
||||
lfd f31, 136(r1) # restore F31
|
||||
lfd f0, 144(r1) # load FPSCR
|
||||
mtfsf 0xff, f0 # restore FPSCR
|
||||
|
||||
lwz r13, 152(r1) # restore R13
|
||||
lwz r14, 156(r1) # restore R14
|
||||
lwz r15, 160(r1) # restore R15
|
||||
lwz r16, 164(r1) # restore R16
|
||||
lwz r17, 168(r1) # restore R17
|
||||
lwz r18, 172(r1) # restore R18
|
||||
lwz r19, 176(r1) # restore R19
|
||||
lwz r20, 180(r1) # restore R20
|
||||
lwz r21, 184(r1) # restore R21
|
||||
lwz r22, 188(r1) # restore R22
|
||||
lwz r23, 192(r1) # restore R23
|
||||
lwz r24, 196(r1) # restore R24
|
||||
lwz r25, 200(r1) # restore R25
|
||||
lwz r26, 204(r1) # restore R26
|
||||
lwz r27, 208(r1) # restore R27
|
||||
lwz r28, 212(r1) # restore R28
|
||||
lwz r29, 216(r1) # restore R29
|
||||
lwz r30, 220(r1) # restore R30
|
||||
lwz r31, 224(r1) # restore R31
|
||||
lwz r3, 228(r1) # restore hidden
|
||||
|
||||
# restore CR
|
||||
lwz r0, 232(r1)
|
||||
mtcr r0
|
||||
# restore LR
|
||||
lwz r0, 236(r1)
|
||||
mtlr r0
|
||||
# load PC
|
||||
lwz r0, 240(r1)
|
||||
# restore CTR
|
||||
mtctr r0
|
||||
|
||||
# adjust stack
|
||||
addi r1, r1, 244
|
||||
|
||||
# return transfer_t
|
||||
stw r6, 0(r3)
|
||||
stw r5, 4(r3)
|
||||
|
||||
# jump to context
|
||||
bctr
|
221
Zend/asm/jump_ppc64_sysv_elf_gas.S
Normal file
221
Zend/asm/jump_ppc64_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC | R14 | R15 | R16 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R17 | R18 | R19 | R20 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R21 | R22 | R23 | R24 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R25 | R26 | R27 | R28 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R29 | R30 | R31 | hidden | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | CR | LR | PC | back-chain| *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | cr saved | lr saved | compiler | linker | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC saved | FCTX | DATA | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "jump_ppc64_sysv_elf_gas.S"
|
||||
.globl jump_fcontext
|
||||
#if _CALL_ELF == 2
|
||||
.text
|
||||
.align 2
|
||||
jump_fcontext:
|
||||
addis %r2, %r12, .TOC.-jump_fcontext@ha
|
||||
addi %r2, %r2, .TOC.-jump_fcontext@l
|
||||
.localentry jump_fcontext, . - jump_fcontext
|
||||
#else
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
jump_fcontext:
|
||||
# ifdef _CALL_LINUX
|
||||
.quad .L.jump_fcontext,.TOC.@tocbase,0
|
||||
.type jump_fcontext,@function
|
||||
.text
|
||||
.align 2
|
||||
.L.jump_fcontext:
|
||||
# else
|
||||
.hidden .jump_fcontext
|
||||
.globl .jump_fcontext
|
||||
.quad .jump_fcontext,.TOC.@tocbase,0
|
||||
.size jump_fcontext,24
|
||||
.type .jump_fcontext,@function
|
||||
.text
|
||||
.align 2
|
||||
.jump_fcontext:
|
||||
# endif
|
||||
#endif
|
||||
# reserve space on stack
|
||||
subi %r1, %r1, 184
|
||||
|
||||
#if _CALL_ELF != 2
|
||||
std %r2, 0(%r1) # save TOC
|
||||
#endif
|
||||
std %r14, 8(%r1) # save R14
|
||||
std %r15, 16(%r1) # save R15
|
||||
std %r16, 24(%r1) # save R16
|
||||
std %r17, 32(%r1) # save R17
|
||||
std %r18, 40(%r1) # save R18
|
||||
std %r19, 48(%r1) # save R19
|
||||
std %r20, 56(%r1) # save R20
|
||||
std %r21, 64(%r1) # save R21
|
||||
std %r22, 72(%r1) # save R22
|
||||
std %r23, 80(%r1) # save R23
|
||||
std %r24, 88(%r1) # save R24
|
||||
std %r25, 96(%r1) # save R25
|
||||
std %r26, 104(%r1) # save R26
|
||||
std %r27, 112(%r1) # save R27
|
||||
std %r28, 120(%r1) # save R28
|
||||
std %r29, 128(%r1) # save R29
|
||||
std %r30, 136(%r1) # save R30
|
||||
std %r31, 144(%r1) # save R31
|
||||
#if _CALL_ELF != 2
|
||||
std %r3, 152(%r1) # save hidden
|
||||
#endif
|
||||
|
||||
# save CR
|
||||
mfcr %r0
|
||||
std %r0, 160(%r1)
|
||||
# save LR
|
||||
mflr %r0
|
||||
std %r0, 168(%r1)
|
||||
# save LR as PC
|
||||
std %r0, 176(%r1)
|
||||
|
||||
# store RSP (pointing to context-data) in R6
|
||||
mr %r6, %r1
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
# restore RSP (pointing to context-data) from R3
|
||||
mr %r1, %r3
|
||||
#else
|
||||
# restore RSP (pointing to context-data) from R4
|
||||
mr %r1, %r4
|
||||
|
||||
ld %r2, 0(%r1) # restore TOC
|
||||
#endif
|
||||
ld %r14, 8(%r1) # restore R14
|
||||
ld %r15, 16(%r1) # restore R15
|
||||
ld %r16, 24(%r1) # restore R16
|
||||
ld %r17, 32(%r1) # restore R17
|
||||
ld %r18, 40(%r1) # restore R18
|
||||
ld %r19, 48(%r1) # restore R19
|
||||
ld %r20, 56(%r1) # restore R20
|
||||
ld %r21, 64(%r1) # restore R21
|
||||
ld %r22, 72(%r1) # restore R22
|
||||
ld %r23, 80(%r1) # restore R23
|
||||
ld %r24, 88(%r1) # restore R24
|
||||
ld %r25, 96(%r1) # restore R25
|
||||
ld %r26, 104(%r1) # restore R26
|
||||
ld %r27, 112(%r1) # restore R27
|
||||
ld %r28, 120(%r1) # restore R28
|
||||
ld %r29, 128(%r1) # restore R29
|
||||
ld %r30, 136(%r1) # restore R30
|
||||
ld %r31, 144(%r1) # restore R31
|
||||
#if _CALL_ELF != 2
|
||||
ld %r3, 152(%r1) # restore hidden
|
||||
#endif
|
||||
|
||||
# restore CR
|
||||
ld %r0, 160(%r1)
|
||||
mtcr %r0
|
||||
# restore LR
|
||||
ld %r0, 168(%r1)
|
||||
mtlr %r0
|
||||
|
||||
# load PC
|
||||
ld %r12, 176(%r1)
|
||||
# restore CTR
|
||||
mtctr %r12
|
||||
|
||||
# adjust stack
|
||||
addi %r1, %r1, 184
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
# copy transfer_t into transfer_fn arg registers
|
||||
mr %r3, %r6
|
||||
# arg pointer already in %r4
|
||||
|
||||
# jump to context
|
||||
bctr
|
||||
.size jump_fcontext, .-jump_fcontext
|
||||
#else
|
||||
# zero in r3 indicates first jump to context-function
|
||||
cmpdi %r3, 0
|
||||
beq use_entry_arg
|
||||
|
||||
# return transfer_t
|
||||
std %r6, 0(%r3)
|
||||
std %r5, 8(%r3)
|
||||
|
||||
# jump to context
|
||||
bctr
|
||||
|
||||
use_entry_arg:
|
||||
# copy transfer_t into transfer_fn arg registers
|
||||
mr %r3, %r6
|
||||
mr %r4, %r5
|
||||
|
||||
# jump to context
|
||||
bctr
|
||||
# ifdef _CALL_LINUX
|
||||
.size .jump_fcontext, .-.L.jump_fcontext
|
||||
# else
|
||||
.size .jump_fcontext, .-.jump_fcontext
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
164
Zend/asm/jump_ppc64_sysv_macho_gas.S
Normal file
164
Zend/asm/jump_ppc64_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC | R14 | R15 | R16 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R17 | R18 | R19 | R20 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R21 | R22 | R23 | R24 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R25 | R26 | R27 | R28 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R29 | R30 | R31 | hidden | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | CR | LR | PC | back-chain| *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | cr saved | lr saved | compiler | linker | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC saved | FCTX | DATA | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.globl _jump_fcontext
|
||||
|
||||
_jump_fcontext:
|
||||
; reserve space on stack
|
||||
subi r1, r1, 184
|
||||
|
||||
std r14, 8(r1) ; save R14
|
||||
std r15, 16(r1) ; save R15
|
||||
std r16, 24(r1) ; save R16
|
||||
std r17, 32(r1) ; save R17
|
||||
std r18, 40(r1) ; save R18
|
||||
std r19, 48(r1) ; save R19
|
||||
std r20, 56(r1) ; save R20
|
||||
std r21, 64(r1) ; save R21
|
||||
std r22, 72(r1) ; save R22
|
||||
std r23, 80(r1) ; save R23
|
||||
std r24, 88(r1) ; save R24
|
||||
std r25, 96(r1) ; save R25
|
||||
std r26, 104(r1) ; save R26
|
||||
std r27, 112(r1) ; save R27
|
||||
std r28, 120(r1) ; save R28
|
||||
std r29, 128(r1) ; save R29
|
||||
std r30, 136(r1) ; save R30
|
||||
std r31, 144(r1) ; save R31
|
||||
std r3, 152(r1) ; save hidden
|
||||
|
||||
; save CR
|
||||
mfcr r0
|
||||
std r0, 160(r1)
|
||||
; save LR
|
||||
mflr r0
|
||||
std r0, 168(r1)
|
||||
; save LR as PC
|
||||
std r0, 176(r1)
|
||||
|
||||
; store RSP (pointing to context-data) in R6
|
||||
mr r6, r1
|
||||
|
||||
; restore RSP (pointing to context-data) from R4
|
||||
mr r1, r4
|
||||
|
||||
ld r14, 8(r1) ; restore R14
|
||||
ld r15, 16(r1) ; restore R15
|
||||
ld r16, 24(r1) ; restore R16
|
||||
ld r17, 32(r1) ; restore R17
|
||||
ld r18, 40(r1) ; restore R18
|
||||
ld r19, 48(r1) ; restore R19
|
||||
ld r20, 56(r1) ; restore R20
|
||||
ld r21, 64(r1) ; restore R21
|
||||
ld r22, 72(r1) ; restore R22
|
||||
ld r23, 80(r1) ; restore R23
|
||||
ld r24, 88(r1) ; restore R24
|
||||
ld r25, 96(r1) ; restore R25
|
||||
ld r26, 104(r1) ; restore R26
|
||||
ld r27, 112(r1) ; restore R27
|
||||
ld r28, 120(r1) ; restore R28
|
||||
ld r29, 128(r1) ; restore R29
|
||||
ld r30, 136(r1) ; restore R30
|
||||
ld r31, 144(r1) ; restore R31
|
||||
ld r3, 152(r1) ; restore hidden
|
||||
|
||||
; restore CR
|
||||
ld r0, 160(r1)
|
||||
mtcr r0
|
||||
; restore LR
|
||||
ld r0, 168(r1)
|
||||
mtlr r0
|
||||
|
||||
; load PC
|
||||
ld r12, 176(r1)
|
||||
# restore CTR
|
||||
mtctr r12
|
||||
|
||||
# adjust stack
|
||||
addi r1, r1, 184
|
||||
|
||||
# zero in r3 indicates first jump to context-function
|
||||
cmpdi r3, 0
|
||||
beq use_entry_arg
|
||||
|
||||
# return transfer_t
|
||||
std r6, 0(r3)
|
||||
std r5, 8(r3)
|
||||
|
||||
# jump to context
|
||||
bctr
|
||||
|
||||
use_entry_arg:
|
||||
# copy transfer_t into transfer_fn arg registers
|
||||
mr r3, r6
|
||||
mr r4, r5
|
||||
|
||||
# jump to context
|
||||
bctr
|
156
Zend/asm/jump_s390x_sysv_elf_gas.S
Normal file
156
Zend/asm/jump_s390x_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*******************************************************
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 8 | 16 | 24 | *
|
||||
* ------------------------------------------------- *
|
||||
* | t.fctx | t.data | r2 | r6 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 40 | 48 | 56 | *
|
||||
* ------------------------------------------------- *
|
||||
* | r7 | r8 | r9 | r10 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 72 | 80 | 88 | *
|
||||
* ------------------------------------------------- *
|
||||
* | r11 | r12 | r13 | r14 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 104 | 112 | 120 | *
|
||||
* ------------------------------------------------- *
|
||||
* | f8 | f9 | f10 | f11 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 136 | 144 | 152 | *
|
||||
* ------------------------------------------------- *
|
||||
* | f12 | f13 | f14 | f15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 168 | 176 | | *
|
||||
* ------------------------------------------------- *
|
||||
* | fpc | pc | | | *
|
||||
* ------------------------------------------------- *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.align 8
|
||||
.global jump_fcontext
|
||||
.type jump_fcontext, @function
|
||||
|
||||
#define ARG_OFFSET 0
|
||||
#define GR_OFFSET 16
|
||||
#define FP_OFFSET 96
|
||||
#define FPC_OFFSET 160
|
||||
#define PC_OFFSET 168
|
||||
#define CONTEXT_SIZE 176
|
||||
|
||||
#define REG_SAVE_AREA_SIZE 160
|
||||
|
||||
/*
|
||||
|
||||
typedef void* fcontext_t;
|
||||
|
||||
struct transfer_t {
|
||||
fcontext_t fctx;
|
||||
void * data;
|
||||
};
|
||||
|
||||
transfer_t jump_fcontext( fcontext_t const to,
|
||||
void * data);
|
||||
|
||||
Incoming args
|
||||
r2 - Hidden argument to the location where the return transfer_t needs to be returned
|
||||
r3 - Context we want to switch to
|
||||
r4 - Data pointer
|
||||
|
||||
*/
|
||||
|
||||
jump_fcontext:
|
||||
.machine "z10"
|
||||
/* Reserve stack space to store the current context. */
|
||||
aghi %r15,-CONTEXT_SIZE
|
||||
|
||||
/* Save the argument register holding the location of the return value. */
|
||||
stg %r2,GR_OFFSET(%r15)
|
||||
|
||||
/* Save the call-saved general purpose registers. */
|
||||
stmg %r6,%r14,GR_OFFSET+8(%r15)
|
||||
|
||||
/* Save call-saved floating point registers. */
|
||||
std %f8,FP_OFFSET(%r15)
|
||||
std %f9,FP_OFFSET+8(%r15)
|
||||
std %f10,FP_OFFSET+16(%r15)
|
||||
std %f11,FP_OFFSET+24(%r15)
|
||||
std %f12,FP_OFFSET+32(%r15)
|
||||
std %f13,FP_OFFSET+40(%r15)
|
||||
std %f14,FP_OFFSET+48(%r15)
|
||||
std %f15,FP_OFFSET+56(%r15)
|
||||
|
||||
/* Save the return address as current pc. */
|
||||
stg %r14,PC_OFFSET(%r15)
|
||||
|
||||
/* Save the floating point control register. */
|
||||
stfpc FPC_OFFSET(%r15)
|
||||
|
||||
/* Backup the stack pointer pointing to the old context-data into r1. */
|
||||
lgr %r1,%r15
|
||||
|
||||
/* Load the new context pointer as stack pointer. */
|
||||
lgr %r15,%r3
|
||||
|
||||
/* Restore the call-saved GPRs from the new context. */
|
||||
lmg %r6,%r14,GR_OFFSET+8(%r15)
|
||||
|
||||
/* Restore call-saved floating point registers. */
|
||||
ld %f8,FP_OFFSET(%r15)
|
||||
ld %f9,FP_OFFSET+8(%r15)
|
||||
ld %f10,FP_OFFSET+16(%r15)
|
||||
ld %f11,FP_OFFSET+24(%r15)
|
||||
ld %f12,FP_OFFSET+32(%r15)
|
||||
ld %f13,FP_OFFSET+40(%r15)
|
||||
ld %f14,FP_OFFSET+48(%r15)
|
||||
ld %f15,FP_OFFSET+56(%r15)
|
||||
|
||||
/* Load the floating point control register. */
|
||||
lfpc FPC_OFFSET(%r15)
|
||||
|
||||
/* Restore PC - the location where we will jump to at the end. */
|
||||
lg %r5,PC_OFFSET(%r15)
|
||||
|
||||
ltg %r2,GR_OFFSET(%r15)
|
||||
jnz use_return_slot
|
||||
|
||||
/* We restore a make_fcontext context. Use the function
|
||||
argument slot in the context we just saved and allocate the
|
||||
register save area for the target function. */
|
||||
la %r2,ARG_OFFSET(%r1)
|
||||
aghi %r15,-REG_SAVE_AREA_SIZE
|
||||
|
||||
use_return_slot:
|
||||
/* Save the two fields in transfer_t. When calling a
|
||||
make_fcontext function this becomes the function argument of
|
||||
the target function, otherwise it will be the return value of
|
||||
jump_fcontext. */
|
||||
stg %r1,0(%r2)
|
||||
stg %r4,8(%r2)
|
||||
|
||||
/* Free the restored context. */
|
||||
aghi %r15,CONTEXT_SIZE
|
||||
|
||||
/* Jump to the PC loaded from the new context. */
|
||||
br %r5
|
||||
|
||||
|
||||
.size jump_fcontext,.-jump_fcontext
|
||||
.section .note.GNU-stack,"",%progbits
|
205
Zend/asm/jump_x86_64_ms_pe_masm.asm
Normal file
205
Zend/asm/jump_x86_64_ms_pe_masm.asm
Normal file
|
@ -0,0 +1,205 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; 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)
|
||||
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | limit | base | R12 | R13 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | R14 | R15 | RDI | RSI |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | RBX | RBP | hidden | RIP |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | parameter area |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | FCTX | DATA | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
jump_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
|
||||
.endprolog
|
||||
|
||||
; prepare stack
|
||||
lea rsp, [rsp-0118h]
|
||||
|
||||
IFNDEF BOOST_USE_TSX
|
||||
; save XMM storage
|
||||
movaps [rsp], xmm6
|
||||
movaps [rsp+010h], xmm7
|
||||
movaps [rsp+020h], xmm8
|
||||
movaps [rsp+030h], xmm9
|
||||
movaps [rsp+040h], xmm10
|
||||
movaps [rsp+050h], xmm11
|
||||
movaps [rsp+060h], xmm12
|
||||
movaps [rsp+070h], xmm13
|
||||
movaps [rsp+080h], xmm14
|
||||
movaps [rsp+090h], xmm15
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [rsp+0a0h]
|
||||
; save x87 control-word
|
||||
fnstcw [rsp+0a4h]
|
||||
ENDIF
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; save fiber local storage
|
||||
mov rax, [r10+020h]
|
||||
mov [rsp+0b0h], rax
|
||||
; save current deallocation stack
|
||||
mov rax, [r10+01478h]
|
||||
mov [rsp+0b8h], rax
|
||||
; save current stack limit
|
||||
mov rax, [r10+010h]
|
||||
mov [rsp+0c0h], rax
|
||||
; save current stack base
|
||||
mov rax, [r10+08h]
|
||||
mov [rsp+0c8h], rax
|
||||
|
||||
mov [rsp+0d0h], r12 ; save R12
|
||||
mov [rsp+0d8h], r13 ; save R13
|
||||
mov [rsp+0e0h], r14 ; save R14
|
||||
mov [rsp+0e8h], r15 ; save R15
|
||||
mov [rsp+0f0h], rdi ; save RDI
|
||||
mov [rsp+0f8h], rsi ; save RSI
|
||||
mov [rsp+0100h], rbx ; save RBX
|
||||
mov [rsp+0108h], rbp ; save RBP
|
||||
|
||||
mov [rsp+0110h], rcx ; save hidden address of transport_t
|
||||
|
||||
; preserve RSP (pointing to context-data) in R9
|
||||
mov r9, rsp
|
||||
|
||||
; restore RSP (pointing to context-data) from RDX
|
||||
mov rsp, rdx
|
||||
|
||||
IFNDEF BOOST_USE_TSX
|
||||
; restore XMM storage
|
||||
movaps xmm6, [rsp]
|
||||
movaps xmm7, [rsp+010h]
|
||||
movaps xmm8, [rsp+020h]
|
||||
movaps xmm9, [rsp+030h]
|
||||
movaps xmm10, [rsp+040h]
|
||||
movaps xmm11, [rsp+050h]
|
||||
movaps xmm12, [rsp+060h]
|
||||
movaps xmm13, [rsp+070h]
|
||||
movaps xmm14, [rsp+080h]
|
||||
movaps xmm15, [rsp+090h]
|
||||
; restore MMX control- and status-word
|
||||
ldmxcsr [rsp+0a0h]
|
||||
; save x87 control-word
|
||||
fldcw [rsp+0a4h]
|
||||
ENDIF
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; restore fiber local storage
|
||||
mov rax, [rsp+0b0h]
|
||||
mov [r10+020h], rax
|
||||
; restore current deallocation stack
|
||||
mov rax, [rsp+0b8h]
|
||||
mov [r10+01478h], rax
|
||||
; restore current stack limit
|
||||
mov rax, [rsp+0c0h]
|
||||
mov [r10+010h], rax
|
||||
; restore current stack base
|
||||
mov rax, [rsp+0c8h]
|
||||
mov [r10+08h], rax
|
||||
|
||||
mov r12, [rsp+0d0h] ; restore R12
|
||||
mov r13, [rsp+0d8h] ; restore R13
|
||||
mov r14, [rsp+0e0h] ; restore R14
|
||||
mov r15, [rsp+0e8h] ; restore R15
|
||||
mov rdi, [rsp+0f0h] ; restore RDI
|
||||
mov rsi, [rsp+0f8h] ; restore RSI
|
||||
mov rbx, [rsp+0100h] ; restore RBX
|
||||
mov rbp, [rsp+0108h] ; restore RBP
|
||||
|
||||
mov rax, [rsp+0110h] ; restore hidden address of transport_t
|
||||
|
||||
; prepare stack
|
||||
lea rsp, [rsp+0118h]
|
||||
|
||||
; load return-address
|
||||
pop r10
|
||||
|
||||
; transport_t returned in RAX
|
||||
; return parent fcontext_t
|
||||
mov [rax], r9
|
||||
; return data
|
||||
mov [rax+08h], r8
|
||||
|
||||
; transport_t as 1.arg of context-function
|
||||
mov rcx, rax
|
||||
|
||||
; indirect jump to context
|
||||
jmp r10
|
||||
jump_fcontext ENDP
|
||||
END
|
91
Zend/asm/jump_x86_64_sysv_elf_gas.S
Normal file
91
Zend/asm/jump_x86_64_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R15 | RBX | RBP | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.file "jump_x86_64_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.type jump_fcontext,@function
|
||||
.align 16
|
||||
jump_fcontext:
|
||||
leaq -0x38(%rsp), %rsp /* prepare stack */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
stmxcsr (%rsp) /* save MMX control- and status-word */
|
||||
fnstcw 0x4(%rsp) /* save x87 control-word */
|
||||
#endif
|
||||
|
||||
movq %r12, 0x8(%rsp) /* save R12 */
|
||||
movq %r13, 0x10(%rsp) /* save R13 */
|
||||
movq %r14, 0x18(%rsp) /* save R14 */
|
||||
movq %r15, 0x20(%rsp) /* save R15 */
|
||||
movq %rbx, 0x28(%rsp) /* save RBX */
|
||||
movq %rbp, 0x30(%rsp) /* save RBP */
|
||||
|
||||
/* store RSP (pointing to context-data) in RAX */
|
||||
movq %rsp, %rax
|
||||
|
||||
/* restore RSP (pointing to context-data) from RDI */
|
||||
movq %rdi, %rsp
|
||||
|
||||
movq 0x38(%rsp), %r8 /* restore return-address */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
ldmxcsr (%rsp) /* restore MMX control- and status-word */
|
||||
fldcw 0x4(%rsp) /* restore x87 control-word */
|
||||
#endif
|
||||
|
||||
movq 0x8(%rsp), %r12 /* restore R12 */
|
||||
movq 0x10(%rsp), %r13 /* restore R13 */
|
||||
movq 0x18(%rsp), %r14 /* restore R14 */
|
||||
movq 0x20(%rsp), %r15 /* restore R15 */
|
||||
movq 0x28(%rsp), %rbx /* restore RBX */
|
||||
movq 0x30(%rsp), %rbp /* restore RBP */
|
||||
|
||||
leaq 0x40(%rsp), %rsp /* prepare stack */
|
||||
|
||||
/* return transfer_t from jump */
|
||||
#if !defined(_ILP32)
|
||||
/* RAX == fctx, RDX == data */
|
||||
movq %rsi, %rdx
|
||||
#else
|
||||
/* RAX == data:fctx */
|
||||
salq $32, %rsi
|
||||
orq %rsi, %rax
|
||||
#endif
|
||||
/* pass transfer_t as first arg in context function */
|
||||
#if !defined(_ILP32)
|
||||
/* RDI == fctx, RSI == data */
|
||||
#else
|
||||
/* RDI == data:fctx */
|
||||
#endif
|
||||
movq %rax, %rdi
|
||||
|
||||
/* indirect jump to context */
|
||||
jmp *%r8
|
||||
.size jump_fcontext,.-jump_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
75
Zend/asm/jump_x86_64_sysv_macho_gas.S
Normal file
75
Zend/asm/jump_x86_64_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R15 | RBX | RBP | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl _jump_fcontext
|
||||
.align 8
|
||||
_jump_fcontext:
|
||||
leaq -0x38(%rsp), %rsp /* prepare stack */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
stmxcsr (%rsp) /* save MMX control- and status-word */
|
||||
fnstcw 0x4(%rsp) /* save x87 control-word */
|
||||
#endif
|
||||
|
||||
movq %r12, 0x8(%rsp) /* save R12 */
|
||||
movq %r13, 0x10(%rsp) /* save R13 */
|
||||
movq %r14, 0x18(%rsp) /* save R14 */
|
||||
movq %r15, 0x20(%rsp) /* save R15 */
|
||||
movq %rbx, 0x28(%rsp) /* save RBX */
|
||||
movq %rbp, 0x30(%rsp) /* save RBP */
|
||||
|
||||
/* store RSP (pointing to context-data) in RAX */
|
||||
movq %rsp, %rax
|
||||
|
||||
/* restore RSP (pointing to context-data) from RDI */
|
||||
movq %rdi, %rsp
|
||||
|
||||
movq 0x38(%rsp), %r8 /* restore return-address */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
ldmxcsr (%rsp) /* restore MMX control- and status-word */
|
||||
fldcw 0x4(%rsp) /* restore x87 control-word */
|
||||
#endif
|
||||
|
||||
movq 0x8(%rsp), %r12 /* restore R12 */
|
||||
movq 0x10(%rsp), %r13 /* restore R13 */
|
||||
movq 0x18(%rsp), %r14 /* restore R14 */
|
||||
movq 0x20(%rsp), %r15 /* restore R15 */
|
||||
movq 0x28(%rsp), %rbx /* restore RBX */
|
||||
movq 0x30(%rsp), %rbp /* restore RBP */
|
||||
|
||||
leaq 0x40(%rsp), %rsp /* prepare stack */
|
||||
|
||||
/* return transfer_t from jump */
|
||||
/* RAX == fctx, RDX == data */
|
||||
movq %rsi, %rdx
|
||||
/* pass transfer_t as first arg in context function */
|
||||
/* RDI == fctx, RSI == data */
|
||||
movq %rax, %rdi
|
||||
|
||||
/* indirect jump to context */
|
||||
jmp *%r8
|
85
Zend/asm/make_arm64_aapcs_elf_gas.S
Normal file
85
Zend/asm/make_arm64_aapcs_elf_gas.S
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright Edward Nevill + Oliver Kowalke 2015
|
||||
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)
|
||||
*/
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d8 | d9 | d10 | d11 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d12 | d13 | d14 | d15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x19 | x20 | x21 | x22 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x23 | x24 | x25 | x26 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x27 | x28 | FP | LR | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | | | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0xa0| 0xa4| 0xa8| 0xac| | | *
|
||||
* ------------------------------------------------- *
|
||||
* | PC | align | | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "make_arm64_aapcs_elf_gas.S"
|
||||
.text
|
||||
.align 2
|
||||
.global make_fcontext
|
||||
.type make_fcontext, %function
|
||||
make_fcontext:
|
||||
# shift address in x0 (allocated stack) to lower 16 byte boundary
|
||||
and x0, x0, ~0xF
|
||||
|
||||
# reserve space for context-data on context-stack
|
||||
sub x0, x0, #0xb0
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
# store address as a PC to jump in
|
||||
str x2, [x0, #0xa0]
|
||||
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns (LR register)
|
||||
adr x1, finish
|
||||
str x1, [x0, #0x98]
|
||||
|
||||
ret x30 // return pointer to context-data (x0)
|
||||
|
||||
finish:
|
||||
# exit code is zero
|
||||
mov x0, #0
|
||||
# exit application
|
||||
bl _exit
|
||||
|
||||
.size make_fcontext,.-make_fcontext
|
||||
# Mark that we don't need executable stack.
|
||||
.section .note.GNU-stack,"",%progbits
|
83
Zend/asm/make_arm64_aapcs_macho_gas.S
Normal file
83
Zend/asm/make_arm64_aapcs_macho_gas.S
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright Edward Nevill + Oliver Kowalke 2015
|
||||
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)
|
||||
*/
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d8 | d9 | d10 | d11 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | d12 | d13 | d14 | d15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x19 | x20 | x21 | x22 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x23 | x24 | x25 | x26 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
|
||||
* ------------------------------------------------- *
|
||||
* | x27 | x28 | FP | LR | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | | | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0xa0| 0xa4| 0xa8| 0xac| | | *
|
||||
* ------------------------------------------------- *
|
||||
* | PC | align | | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
.balign 16
|
||||
|
||||
_make_fcontext:
|
||||
; shift address in x0 (allocated stack) to lower 16 byte boundary
|
||||
and x0, x0, ~0xF
|
||||
|
||||
; reserve space for context-data on context-stack
|
||||
sub x0, x0, #0xb0
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
; store address as a PC to jump in
|
||||
str x2, [x0, #0xa0]
|
||||
|
||||
adr x1, finish
|
||||
|
||||
; save address of finish as return-address for context-function
|
||||
; will be entered after context-function returns (LR register)
|
||||
str x1, [x0, #0x98]
|
||||
|
||||
ret lr ; return pointer to context-data (x0)
|
||||
|
||||
finish:
|
||||
; exit code is zero
|
||||
mov x0, #0
|
||||
; exit application
|
||||
bl __exit
|
||||
|
||||
|
81
Zend/asm/make_arm_aapcs_elf_gas.S
Normal file
81
Zend/asm/make_arm_aapcs_elf_gas.S
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
|
||||
* ------------------------------------------------- *
|
||||
* |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
|
||||
* ------------------------------------------------- *
|
||||
* | v8 | lr | pc | FCTX| DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "make_arm_aapcs_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,%function
|
||||
.syntax unified
|
||||
make_fcontext:
|
||||
@ shift address in A1 to lower 16 byte boundary
|
||||
bic a1, a1, #15
|
||||
|
||||
@ reserve space for context-data on context-stack
|
||||
sub a1, a1, #124
|
||||
|
||||
@ third arg of make_fcontext() == address of context-function
|
||||
str a3, [a1, #104]
|
||||
|
||||
@ compute address of returned transfer_t
|
||||
add a2, a1, #108
|
||||
mov a3, a2
|
||||
str a3, [a1, #64]
|
||||
|
||||
@ compute abs address of label finish
|
||||
adr a2, finish
|
||||
@ save address of finish as return-address for context-function
|
||||
@ will be entered after context-function returns
|
||||
str a2, [a1, #100]
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
#endif
|
||||
|
||||
bx lr @ return pointer to context-data
|
||||
|
||||
finish:
|
||||
@ exit code is zero
|
||||
mov a1, #0
|
||||
@ exit application
|
||||
bl _exit@PLT
|
||||
.size make_fcontext,.-make_fcontext
|
||||
|
||||
@ Mark that we don't need executable stack.
|
||||
.section .note.GNU-stack,"",%progbits
|
71
Zend/asm/make_arm_aapcs_macho_gas.S
Normal file
71
Zend/asm/make_arm_aapcs_macho_gas.S
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
|
||||
* ------------------------------------------------- *
|
||||
* | sjlj|hiddn| v1 | v2 | v3 | v4 | v5 | v6 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
|
||||
* ------------------------------------------------- *
|
||||
* | v7 | v8 | lr | pc | FCTX| DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
.align 2
|
||||
_make_fcontext:
|
||||
@ shift address in A1 to lower 16 byte boundary
|
||||
bic a1, a1, #15
|
||||
|
||||
@ reserve space for context-data on context-stack
|
||||
sub a1, a1, #124
|
||||
|
||||
@ third arg of make_fcontext() == address of context-function
|
||||
str a3, [a1, #108]
|
||||
|
||||
@ compute address of returned transfer_t
|
||||
add a2, a1, #112
|
||||
mov a3, a2
|
||||
str a3, [a1, #68]
|
||||
|
||||
@ compute abs address of label finish
|
||||
adr a2, finish
|
||||
@ save address of finish as return-address for context-function
|
||||
@ will be entered after context-function returns
|
||||
str a2, [a1, #104]
|
||||
|
||||
bx lr @ return pointer to context-data
|
||||
|
||||
finish:
|
||||
@ exit code is zero
|
||||
mov a1, #0
|
||||
@ exit application
|
||||
bl __exit
|
24
Zend/asm/make_combined_sysv_macho_gas.S
Normal file
24
Zend/asm/make_combined_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright Sergue E. Leontiev 2013.
|
||||
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)
|
||||
*/
|
||||
|
||||
// Stub file for universal binary
|
||||
|
||||
#if defined(__i386__)
|
||||
#include "make_i386_sysv_macho_gas.S"
|
||||
#elif defined(__x86_64__)
|
||||
#include "make_x86_64_sysv_macho_gas.S"
|
||||
#elif defined(__ppc__)
|
||||
#include "make_ppc32_sysv_macho_gas.S"
|
||||
#elif defined(__ppc64__)
|
||||
#include "make_ppc64_sysv_macho_gas.S"
|
||||
#elif defined(__arm__)
|
||||
#include "make_arm_aapcs_macho_gas.S"
|
||||
#elif defined(__arm64__)
|
||||
#include "make_arm64_aapcs_macho_gas.S"
|
||||
#else
|
||||
#error "No arch's"
|
||||
#endif
|
140
Zend/asm/make_i386_ms_pe_masm.asm
Normal file
140
Zend/asm/make_i386_ms_pe_masm.asm
Normal file
|
@ -0,0 +1,140 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; 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)
|
||||
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | ESI | EBX | EBP | EIP | to | data | EH NXT |SEH HNDLR|
|
||||
; ---------------------------------------------------------------------------------
|
||||
|
||||
.386
|
||||
.XMM
|
||||
.model flat, c
|
||||
; standard C library function
|
||||
_exit PROTO, value:SDWORD
|
||||
.code
|
||||
|
||||
make_fcontext PROC BOOST_CONTEXT_EXPORT
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
mov eax, [esp+04h]
|
||||
|
||||
; reserve space for first argument of context-function
|
||||
; EAX might already point to a 16byte border
|
||||
lea eax, [eax-08h]
|
||||
|
||||
; shift address in EAX to lower 16 byte boundary
|
||||
and eax, -16
|
||||
|
||||
; reserve space for context-data on context-stack
|
||||
; on context-function entry: (ESP -0x4) % 8 == 0
|
||||
; additional space is required for SEH
|
||||
lea eax, [eax-040h]
|
||||
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [eax]
|
||||
; save x87 control-word
|
||||
fnstcw [eax+04h]
|
||||
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
mov ecx, [esp+04h]
|
||||
; save top address of context stack as 'base'
|
||||
mov [eax+014h], ecx
|
||||
; second arg of make_fcontext() == size of context-stack
|
||||
mov edx, [esp+08h]
|
||||
; negate stack size for LEA instruction (== substraction)
|
||||
neg edx
|
||||
; compute bottom address of context stack (limit)
|
||||
lea ecx, [ecx+edx]
|
||||
; save bottom address of context-stack as 'limit'
|
||||
mov [eax+010h], ecx
|
||||
; save bottom address of context-stack as 'dealloction stack'
|
||||
mov [eax+0ch], ecx
|
||||
; set fiber-storage to zero
|
||||
xor ecx, ecx
|
||||
mov [eax+08h], ecx
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
; stored in EBX
|
||||
mov ecx, [esp+0ch]
|
||||
mov [eax+024h], ecx
|
||||
|
||||
; compute abs address of label trampoline
|
||||
mov ecx, trampoline
|
||||
; save address of trampoline as return-address for context-function
|
||||
; will be entered after calling jump_fcontext() first time
|
||||
mov [eax+02ch], ecx
|
||||
|
||||
; compute abs address of label finish
|
||||
mov ecx, finish
|
||||
; save address of finish as return-address for context-function in EBP
|
||||
; will be entered after context-function returns
|
||||
mov [eax+028h], ecx
|
||||
|
||||
; traverse current seh chain to get the last exception handler installed by Windows
|
||||
; note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default
|
||||
; the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler
|
||||
; at its end by RaiseException all seh-handlers are disregarded if not present and the
|
||||
; program is aborted
|
||||
assume fs:nothing
|
||||
; load NT_TIB into ECX
|
||||
mov ecx, fs:[0h]
|
||||
assume fs:error
|
||||
|
||||
walk:
|
||||
; load 'next' member of current SEH into EDX
|
||||
mov edx, [ecx]
|
||||
; test if 'next' of current SEH is last (== 0xffffffff)
|
||||
inc edx
|
||||
jz found
|
||||
dec edx
|
||||
; exchange content; ECX contains address of next SEH
|
||||
xchg edx, ecx
|
||||
; inspect next SEH
|
||||
jmp walk
|
||||
|
||||
found:
|
||||
; load 'handler' member of SEH == address of last SEH handler installed by Windows
|
||||
mov ecx, [ecx+04h]
|
||||
; save address in ECX as SEH handler for context
|
||||
mov [eax+03ch], ecx
|
||||
; set ECX to -1
|
||||
mov ecx, 0ffffffffh
|
||||
; save ECX as next SEH item
|
||||
mov [eax+038h], ecx
|
||||
; load address of next SEH item
|
||||
lea ecx, [eax+038h]
|
||||
; save next SEH
|
||||
mov [eax+018h], ecx
|
||||
|
||||
ret ; return pointer to context-data
|
||||
|
||||
trampoline:
|
||||
; move transport_t for entering context-function
|
||||
; FCTX == EAX, DATA == EDX
|
||||
mov [esp], eax
|
||||
mov [esp+04h], edx
|
||||
push ebp
|
||||
; jump to context-function
|
||||
jmp ebx
|
||||
|
||||
finish:
|
||||
; exit code is zero
|
||||
xor eax, eax
|
||||
mov [esp], eax
|
||||
; exit application
|
||||
call _exit
|
||||
hlt
|
||||
make_fcontext ENDP
|
||||
END
|
107
Zend/asm/make_i386_sysv_elf_gas.S
Normal file
107
Zend/asm/make_i386_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | to | data | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.file "make_i386_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,@function
|
||||
make_fcontext:
|
||||
/* first arg of make_fcontext() == top of context-stack */
|
||||
movl 0x4(%esp), %eax
|
||||
|
||||
/* reserve space for first argument of context-function
|
||||
eax might already point to a 16byte border */
|
||||
leal -0x8(%eax), %eax
|
||||
|
||||
/* shift address in EAX to lower 16 byte boundary */
|
||||
andl $-16, %eax
|
||||
|
||||
/* reserve space for context-data on context-stack */
|
||||
leal -0x28(%eax), %eax
|
||||
|
||||
/* third arg of make_fcontext() == address of context-function */
|
||||
/* stored in EBX */
|
||||
movl 0xc(%esp), %ecx
|
||||
movl %ecx, 0x10(%eax)
|
||||
|
||||
/* save MMX control- and status-word */
|
||||
stmxcsr (%eax)
|
||||
/* save x87 control-word */
|
||||
fnstcw 0x4(%eax)
|
||||
|
||||
/* return transport_t */
|
||||
/* FCTX == EDI, DATA == ESI */
|
||||
leal 0x8(%eax), %ecx
|
||||
movl %ecx, 0x1c(%eax)
|
||||
|
||||
/* compute abs address of label trampoline */
|
||||
call 1f
|
||||
/* address of trampoline 1 */
|
||||
1: popl %ecx
|
||||
/* compute abs address of label trampoline */
|
||||
addl $trampoline-1b, %ecx
|
||||
/* save address of trampoline as return address */
|
||||
/* will be entered after calling jump_fcontext() first time */
|
||||
movl %ecx, 0x18(%eax)
|
||||
|
||||
/* compute abs address of label finish */
|
||||
call 2f
|
||||
/* address of label 2 */
|
||||
2: popl %ecx
|
||||
/* compute abs address of label finish */
|
||||
addl $finish-2b, %ecx
|
||||
/* save address of finish as return-address for context-function */
|
||||
/* will be entered after context-function returns */
|
||||
movl %ecx, 0x14(%eax)
|
||||
|
||||
ret /* return pointer to context-data */
|
||||
|
||||
trampoline:
|
||||
/* move transport_t for entering context-function */
|
||||
movl %edi, (%esp)
|
||||
movl %esi, 0x4(%esp)
|
||||
pushl %ebp
|
||||
/* jump to context-function */
|
||||
jmp *%ebx
|
||||
|
||||
finish:
|
||||
call 3f
|
||||
/* address of label 3 */
|
||||
3: popl %ebx
|
||||
/* compute address of GOT and store it in EBX */
|
||||
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
|
||||
|
||||
/* exit code is zero */
|
||||
xorl %eax, %eax
|
||||
movl %eax, (%esp)
|
||||
/* exit application */
|
||||
call _exit@PLT
|
||||
hlt
|
||||
.size make_fcontext,.-make_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
90
Zend/asm/make_i386_sysv_macho_gas.S
Normal file
90
Zend/asm/make_i386_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | to | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | data | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
.align 2
|
||||
_make_fcontext:
|
||||
/* first arg of make_fcontext() == top of context-stack */
|
||||
movl 0x4(%esp), %eax
|
||||
|
||||
/* reserve space for first argument of context-function
|
||||
eax might already point to a 16byte border */
|
||||
leal -0x8(%eax), %eax
|
||||
|
||||
/* shift address in EAX to lower 16 byte boundary */
|
||||
andl $-16, %eax
|
||||
|
||||
/* reserve space for context-data on context-stack */
|
||||
leal -0x2c(%eax), %eax
|
||||
|
||||
/* third arg of make_fcontext() == address of context-function */
|
||||
/* stored in EBX */
|
||||
movl 0xc(%esp), %ecx
|
||||
movl %ecx, 0x10(%eax)
|
||||
|
||||
/* save MMX control- and status-word */
|
||||
stmxcsr (%eax)
|
||||
/* save x87 control-word */
|
||||
fnstcw 0x4(%eax)
|
||||
|
||||
/* compute abs address of label trampoline */
|
||||
call 1f
|
||||
/* address of trampoline 1 */
|
||||
1: popl %ecx
|
||||
/* compute abs address of label trampoline */
|
||||
addl $trampoline-1b, %ecx
|
||||
/* save address of trampoline as return address */
|
||||
/* will be entered after calling jump_fcontext() first time */
|
||||
movl %ecx, 0x18(%eax)
|
||||
|
||||
/* compute abs address of label finish */
|
||||
call 2f
|
||||
/* address of label 2 */
|
||||
2: popl %ecx
|
||||
/* compute abs address of label finish */
|
||||
addl $finish-2b, %ecx
|
||||
/* save address of finish as return-address for context-function */
|
||||
/* will be entered after context-function returns */
|
||||
movl %ecx, 0x14(%eax)
|
||||
|
||||
ret /* return pointer to context-data */
|
||||
|
||||
trampoline:
|
||||
/* move transport_t for entering context-function */
|
||||
movl %eax, (%esp)
|
||||
movl %edx, 0x4(%esp)
|
||||
pushl %ebp
|
||||
/* jump to context-function */
|
||||
jmp *%ebx
|
||||
|
||||
finish:
|
||||
/* exit code is zero */
|
||||
xorl %eax, %eax
|
||||
movl %eax, (%esp)
|
||||
/* exit application */
|
||||
call __exit
|
||||
hlt
|
97
Zend/asm/make_mips32_o32_elf_gas.S
Normal file
97
Zend/asm/make_mips32_o32_elf_gas.S
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F20 | F22 | F24 | F26 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F28 | F30 | S0 | S1 | S2 | S3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S4 | S5 | S6 | S7 | FP |hiddn| RA | PC | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | ABI ARGS | GP | FCTX| DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************/
|
||||
|
||||
.file "make_mips32_o32_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,@function
|
||||
.ent make_fcontext
|
||||
make_fcontext:
|
||||
#ifdef __PIC__
|
||||
.set noreorder
|
||||
.cpload $t9
|
||||
.set reorder
|
||||
#endif
|
||||
# shift address in A0 to lower 16 byte boundary
|
||||
li $v1, -16 # 0xfffffffffffffff0
|
||||
and $v0, $v1, $a0
|
||||
|
||||
# reserve space for context-data on context-stack
|
||||
# includes an extra 32 bytes for:
|
||||
# - 16-byte incoming argument area required by mips ABI used when
|
||||
# jump_context calls the initial function
|
||||
# - 4 bytes to save our GP register used in finish
|
||||
# - 8 bytes to as space for transfer_t returned to finish
|
||||
# - 4 bytes for alignment
|
||||
addiu $v0, $v0, -128
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
sw $a2, 92($v0)
|
||||
# save global pointer in context-data
|
||||
sw $gp, 112($v0)
|
||||
|
||||
# compute address of returned transfer_t
|
||||
addiu $t0, $v0, 116
|
||||
sw $t0, 84($v0)
|
||||
|
||||
# compute abs address of label finish
|
||||
la $t9, finish
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns
|
||||
sw $t9, 88($v0)
|
||||
|
||||
jr $ra # return pointer to context-data
|
||||
|
||||
finish:
|
||||
# reload our gp register (needed for la)
|
||||
lw $gp, 16($sp)
|
||||
|
||||
# call _exit(0)
|
||||
# the previous function should have left the 16 bytes incoming argument
|
||||
# area on the stack which we reuse for calling _exit
|
||||
la $t9, _exit
|
||||
move $a0, $zero
|
||||
jr $t9
|
||||
.end make_fcontext
|
||||
.size make_fcontext, .-make_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
96
Zend/asm/make_mips64_n64_elf_gas.S
Normal file
96
Zend/asm/make_mips64_n64_elf_gas.S
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Copyright Jiaxun Yang 2018.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 8 | 16 | 24 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F24 | F25 | F26 | F27 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 40 | 48 | 56 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F28 | F29 | F30 | F31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 72 | 80 | 88 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S0 | S1 | S2 | S3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S4 | S5 | S6 | S7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | FP | GP | RA | PC | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************/
|
||||
|
||||
.file "make_mips64_n64_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 3
|
||||
.type make_fcontext,@function
|
||||
.ent make_fcontext
|
||||
make_fcontext:
|
||||
#ifdef __PIC__
|
||||
.set noreorder
|
||||
.cpload $t9
|
||||
.set reorder
|
||||
#endif
|
||||
# shift address in A0 to lower 16 byte boundary
|
||||
li $v1, 0xfffffffffffffff0
|
||||
and $v0, $v1, $a0
|
||||
|
||||
# reserve space for context-data on context-stack
|
||||
daddiu $v0, $v0, -160
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
sd $a2, 152($v0)
|
||||
# save global pointer in context-data
|
||||
sd $gp, 136($v0)
|
||||
|
||||
# psudo instruction compute abs address of label finish based on GP
|
||||
dla $t9, finish
|
||||
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns
|
||||
sd $t9, 144($v0)
|
||||
|
||||
jr $ra # return pointer to context-data
|
||||
|
||||
finish:
|
||||
# reload our gp register (needed for la)
|
||||
daddiu $t0, $sp, -160
|
||||
ld $gp, 136($t0)
|
||||
|
||||
# call _exit(0)
|
||||
# the previous function should have left the 16 bytes incoming argument
|
||||
# area on the stack which we reuse for calling _exit
|
||||
dla $t9, _exit
|
||||
move $a0, $zero
|
||||
jr $t9
|
||||
.end make_fcontext
|
||||
.size make_fcontext, .-make_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
146
Zend/asm/make_ppc32_sysv_elf_gas.S
Normal file
146
Zend/asm/make_ppc32_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* |bchai|hiddn| fpscr | PC | CR | R14 | R15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R16 | R17 | R18 | R19 | R20 | R21 | R22 | R23 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F14 | F15 | F16 | F17 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F18 | F19 | F20 | F21 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F22 | F23 | F24 | F25 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F26 | F27 | F28 | F29 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------|------------ *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | *
|
||||
* ------------------------|------------ *
|
||||
* | F30 | F31 |bchai| LR | *
|
||||
* ------------------------|------------ *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "make_ppc32_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,@function
|
||||
make_fcontext:
|
||||
# save return address into R6
|
||||
mflr %r6
|
||||
|
||||
# first arg of make_fcontext() == top address of context-function
|
||||
# shift address in R3 to lower 16 byte boundary
|
||||
clrrwi %r3, %r3, 4
|
||||
|
||||
# reserve space on context-stack, including 16 bytes of linkage
|
||||
# and parameter area + 240 bytes of context-data (R1 % 16 == 0)
|
||||
subi %r3, %r3, 16 + 240
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
#ifdef __linux__
|
||||
# save context-function as PC
|
||||
stw %r5, 16(%r3)
|
||||
#else
|
||||
# save context-function for trampoline
|
||||
stw %r5, 248(%r3)
|
||||
#endif
|
||||
|
||||
# set back-chain to zero
|
||||
li %r0, 0
|
||||
stw %r0, 240(%r3)
|
||||
|
||||
# copy FPSCR to new context
|
||||
mffs %f0
|
||||
stfd %f0, 8(%r3)
|
||||
|
||||
#ifdef __linux__
|
||||
# set hidden pointer for returning transfer_t
|
||||
la %r0, 248(%r3)
|
||||
stw %r0, 4(%r3)
|
||||
#endif
|
||||
|
||||
# load address of label 1 into R4
|
||||
bl 1f
|
||||
1: mflr %r4
|
||||
#ifndef __linux__
|
||||
# compute abs address of trampoline, use as PC
|
||||
addi %r7, %r4, trampoline - 1b
|
||||
stw %r7, 16(%r3)
|
||||
#endif
|
||||
# compute abs address of label finish
|
||||
addi %r4, %r4, finish - 1b
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns
|
||||
stw %r4, 244(%r3)
|
||||
|
||||
# restore return address from R6
|
||||
mtlr %r6
|
||||
|
||||
blr # return pointer to context-data
|
||||
|
||||
#ifndef __linux__
|
||||
trampoline:
|
||||
# On systems other than Linux, jump_fcontext is returning the
|
||||
# transfer_t in R3:R4, but we need to pass transfer_t * R3 to
|
||||
# our context-function.
|
||||
lwz %r0, 8(%r1) # address of context-function
|
||||
mtctr %r0
|
||||
stw %r3, 8(%r1)
|
||||
stw %r4, 12(%r1)
|
||||
la %r3, 8(%r1) # address of transfer_t
|
||||
bctr
|
||||
#endif
|
||||
|
||||
finish:
|
||||
# Use the secure PLT for _exit(0). If we use the insecure BSS PLT
|
||||
# here, then the linker may use the insecure BSS PLT even if the
|
||||
# C++ compiler wanted the secure PLT.
|
||||
|
||||
# set R30 for secure PLT, large model
|
||||
bl 2f
|
||||
2: mflr %r30
|
||||
addis %r30, %r30, .Ltoc - 2b@ha
|
||||
addi %r30, %r30, .Ltoc - 2b@l
|
||||
|
||||
# call _exit(0) with special addend 0x8000 for large model
|
||||
li %r3, 0
|
||||
bl _exit + 0x8000@plt
|
||||
.size make_fcontext, .-make_fcontext
|
||||
|
||||
/* Provide the GOT pointer for secure PLT, large model. */
|
||||
.section .got2,"aw"
|
||||
.Ltoc = . + 0x8000
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
137
Zend/asm/make_ppc32_sysv_macho_gas.S
Normal file
137
Zend/asm/make_ppc32_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F14 | F15 | F16 | F17 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F18 | F19 | F20 | F21 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F22 | F23 | F24 | F25 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F26 | F27 | F28 | F29 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | F30 | F31 | fpscr | R13 | R14 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R31 |hiddn| CR | LR | PC |bchai|linkr| FCTX| *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | | *
|
||||
* ------------------------------------------------- *
|
||||
* | 256 | | *
|
||||
* ------------------------------------------------- *
|
||||
* | DATA| | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
.align 2
|
||||
_make_fcontext:
|
||||
# save return address into R6
|
||||
mflr r6
|
||||
|
||||
# first arg of make_fcontext() == top address of context-function
|
||||
# shift address in R3 to lower 16 byte boundary
|
||||
clrrwi r3, r3, 4
|
||||
|
||||
# reserve space for context-data on context-stack
|
||||
# including 64 byte of linkage + parameter area (R1 16 == 0)
|
||||
subi r3, r3, 336
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
stw r5, 240(r3)
|
||||
|
||||
# set back-chain to zero
|
||||
li r0, 0
|
||||
stw r0, 244(r3)
|
||||
|
||||
mffs f0 # load FPSCR
|
||||
stfd f0, 144(r3) # save FPSCR
|
||||
|
||||
# compute address of returned transfer_t
|
||||
addi r0, r3, 252
|
||||
mr r4, r0
|
||||
stw r4, 228(r3)
|
||||
|
||||
# load LR
|
||||
mflr r0
|
||||
# jump to label 1
|
||||
bl 1f
|
||||
1:
|
||||
# load LR into R4
|
||||
mflr r4
|
||||
# compute abs address of label finish
|
||||
addi r4, r4, finish - 1b
|
||||
# restore LR
|
||||
mtlr r0
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns
|
||||
stw r4, 236(r3)
|
||||
|
||||
# restore return address from R6
|
||||
mtlr r6
|
||||
|
||||
blr # return pointer to context-data
|
||||
|
||||
finish:
|
||||
# save return address into R0
|
||||
mflr r0
|
||||
# save return address on stack, set up stack frame
|
||||
stw r0, 4(r1)
|
||||
# allocate stack space, R1 16 == 0
|
||||
stwu r1, -16(r1)
|
||||
|
||||
# exit code is zero
|
||||
li r3, 0
|
||||
# exit application
|
||||
bl _exit@plt
|
177
Zend/asm/make_ppc64_sysv_elf_gas.S
Normal file
177
Zend/asm/make_ppc64_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC | R14 | R15 | R16 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R17 | R18 | R19 | R20 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R21 | R22 | R23 | R24 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R25 | R26 | R27 | R28 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R29 | R30 | R31 | hidden | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | CR | LR | PC | back-chain| *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | cr saved | lr saved | compiler | linker | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC saved | FCTX | DATA | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.file "make_ppc64_sysv_elf_gas.S"
|
||||
.globl make_fcontext
|
||||
#if _CALL_ELF == 2
|
||||
.text
|
||||
.align 2
|
||||
make_fcontext:
|
||||
addis %r2, %r12, .TOC.-make_fcontext@ha
|
||||
addi %r2, %r2, .TOC.-make_fcontext@l
|
||||
.localentry make_fcontext, . - make_fcontext
|
||||
#else
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
make_fcontext:
|
||||
# ifdef _CALL_LINUX
|
||||
.quad .L.make_fcontext,.TOC.@tocbase,0
|
||||
.type make_fcontext,@function
|
||||
.text
|
||||
.align 2
|
||||
.L.make_fcontext:
|
||||
# else
|
||||
.hidden .make_fcontext
|
||||
.globl .make_fcontext
|
||||
.quad .make_fcontext,.TOC.@tocbase,0
|
||||
.size make_fcontext,24
|
||||
.type .make_fcontext,@function
|
||||
.text
|
||||
.align 2
|
||||
.make_fcontext:
|
||||
# endif
|
||||
#endif
|
||||
# save return address into R6
|
||||
mflr %r6
|
||||
|
||||
# first arg of make_fcontext() == top address of context-stack
|
||||
# shift address in R3 to lower 16 byte boundary
|
||||
clrrdi %r3, %r3, 4
|
||||
|
||||
# reserve space for context-data on context-stack
|
||||
# including 64 byte of linkage + parameter area (R1 % 16 == 0)
|
||||
subi %r3, %r3, 248
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
# entry point (ELFv2) or descriptor (ELFv1)
|
||||
#if _CALL_ELF == 2
|
||||
# save address of context-function entry point
|
||||
std %r5, 176(%r3)
|
||||
#else
|
||||
# save address of context-function entry point
|
||||
ld %r4, 0(%r5)
|
||||
std %r4, 176(%r3)
|
||||
# save TOC of context-function
|
||||
ld %r4, 8(%r5)
|
||||
std %r4, 0(%r3)
|
||||
#endif
|
||||
|
||||
# set back-chain to zero
|
||||
li %r0, 0
|
||||
std %r0, 184(%r3)
|
||||
|
||||
#if _CALL_ELF != 2
|
||||
# zero in r3 indicates first jump to context-function
|
||||
std %r0, 152(%r3)
|
||||
#endif
|
||||
|
||||
# load LR
|
||||
mflr %r0
|
||||
# jump to label 1
|
||||
bl 1f
|
||||
1:
|
||||
# load LR into R4
|
||||
mflr %r4
|
||||
# compute abs address of label finish
|
||||
addi %r4, %r4, finish - 1b
|
||||
# restore LR
|
||||
mtlr %r0
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns
|
||||
std %r4, 168(%r3)
|
||||
|
||||
# restore return address from R6
|
||||
mtlr %r6
|
||||
|
||||
blr # return pointer to context-data
|
||||
|
||||
finish:
|
||||
# save return address into R0
|
||||
mflr %r0
|
||||
# save return address on stack, set up stack frame
|
||||
std %r0, 8(%r1)
|
||||
# allocate stack space, R1 % 16 == 0
|
||||
stdu %r1, -32(%r1)
|
||||
|
||||
# exit code is zero
|
||||
li %r3, 0
|
||||
# exit application
|
||||
bl _exit
|
||||
nop
|
||||
#if _CALL_ELF == 2
|
||||
.size make_fcontext, .-make_fcontext
|
||||
#else
|
||||
# ifdef _CALL_LINUX
|
||||
.size .make_fcontext, .-.L.make_fcontext
|
||||
# else
|
||||
.size .make_fcontext, .-.make_fcontext
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
126
Zend/asm/make_ppc64_sysv_macho_gas.S
Normal file
126
Zend/asm/make_ppc64_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC | R14 | R15 | R16 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R17 | R18 | R19 | R20 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R21 | R22 | R23 | R24 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R25 | R26 | R27 | R28 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | R29 | R30 | R31 | hidden | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
|
||||
* ------------------------------------------------- *
|
||||
* | CR | LR | PC | back-chain| *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
|
||||
* ------------------------------------------------- *
|
||||
* | cr saved | lr saved | compiler | linker | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
|
||||
* ------------------------------------------------- *
|
||||
* | TOC saved | FCTX | DATA | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
_make_fcontext:
|
||||
; save return address into R6
|
||||
mflr r6
|
||||
|
||||
; first arg of make_fcontext() == top address of context-function
|
||||
; shift address in R3 to lower 16 byte boundary
|
||||
clrrwi r3, r3, 4
|
||||
|
||||
; reserve space for context-data on context-stack
|
||||
; including 64 byte of linkage + parameter area (R1 16 == 0)
|
||||
subi r3, r3, 248
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
stw r5, 176(r3)
|
||||
|
||||
; set back-chain to zero
|
||||
li %r0, 0
|
||||
std %r0, 184(%r3)
|
||||
|
||||
; compute address of returned transfer_t
|
||||
addi %r0, %r3, 232
|
||||
mr %r4, %r0
|
||||
std %r4, 152(%r3)
|
||||
|
||||
; load LR
|
||||
mflr r0
|
||||
; jump to label 1
|
||||
bl l1
|
||||
l1:
|
||||
; load LR into R4
|
||||
mflr r4
|
||||
; compute abs address of label finish
|
||||
addi r4, r4, lo16((finish - .) + 4)
|
||||
; restore LR
|
||||
mtlr r0
|
||||
; save address of finish as return-address for context-function
|
||||
; will be entered after context-function returns
|
||||
std r4, 168(r3)
|
||||
|
||||
; restore return address from R6
|
||||
mtlr r6
|
||||
|
||||
blr ; return pointer to context-data
|
||||
|
||||
finish:
|
||||
; save return address into R0
|
||||
mflr r0
|
||||
; save return address on stack, set up stack frame
|
||||
stw r0, 8(r1)
|
||||
; allocate stack space, R1 16 == 0
|
||||
stwu r1, -32(r1)
|
||||
|
||||
; set return value to zero
|
||||
li r3, 0
|
||||
; exit application
|
||||
bl __exit
|
||||
nop
|
108
Zend/asm/make_s390x_sysv_elf_gas.S
Normal file
108
Zend/asm/make_s390x_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*******************************************************
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 8 | 16 | 24 | *
|
||||
* ------------------------------------------------- *
|
||||
* | t.fctx | t.data | r2 | r6 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 40 | 48 | 56 | *
|
||||
* ------------------------------------------------- *
|
||||
* | r7 | r8 | r9 | r10 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 72 | 80 | 88 | *
|
||||
* ------------------------------------------------- *
|
||||
* | r11 | r12 | r13 | r14 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 104 | 112 | 120 | *
|
||||
* ------------------------------------------------- *
|
||||
* | f8 | f9 | f10 | f11 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 136 | 144 | 152 | *
|
||||
* ------------------------------------------------- *
|
||||
* | f12 | f13 | f14 | f15 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 160 | 168 | 176 | | *
|
||||
* ------------------------------------------------- *
|
||||
* | fpc | pc | | | *
|
||||
* ------------------------------------------------- *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.align 8
|
||||
.global make_fcontext
|
||||
.type make_fcontext, @function
|
||||
|
||||
#define ARG_OFFSET 0
|
||||
#define GR_OFFSET 16
|
||||
#define R14_OFFSET 88
|
||||
#define FP_OFFSET 96
|
||||
#define FPC_OFFSET 160
|
||||
#define PC_OFFSET 168
|
||||
#define CONTEXT_SIZE 176
|
||||
|
||||
/*
|
||||
|
||||
fcontext_t make_fcontext( void * sp, std::size_t size, void (* fn)( transfer_t) );
|
||||
|
||||
Create and return a context below SP to call FN.
|
||||
|
||||
Incoming args
|
||||
r2 - The stack location where to create the context
|
||||
r3 - The size of the context
|
||||
r4 - The address of the context function
|
||||
|
||||
*/
|
||||
|
||||
make_fcontext:
|
||||
.machine "z10"
|
||||
/* Align the stack to an 8 byte boundary. */
|
||||
nill %r2,0xfff0
|
||||
|
||||
/* Allocate stack space for the context. */
|
||||
aghi %r2,-CONTEXT_SIZE
|
||||
|
||||
/* Set the r2 save slot to zero. This indicates jump_fcontext
|
||||
that this is a special context. */
|
||||
mvghi GR_OFFSET(%r2),0
|
||||
|
||||
/* Save the floating point control register. */
|
||||
stfpc FPC_OFFSET(%r2)
|
||||
|
||||
/* Store the address of the target function as new pc. */
|
||||
stg %r4,PC_OFFSET(%r2)
|
||||
|
||||
/* Store a pointer to the finish routine as r14. If a function
|
||||
called via context routines just returns that value will be
|
||||
loaded and used as return address. Hence the program will
|
||||
just exit. */
|
||||
larl %r1,finish
|
||||
stg %r1,R14_OFFSET(%r2)
|
||||
|
||||
/* Return as usual with the new context returned in r2. */
|
||||
br %r14
|
||||
|
||||
finish:
|
||||
/* In finish tasks, you load the exit code and exit the
|
||||
make_fcontext This is called when the context-function is
|
||||
entirely executed. */
|
||||
lghi %r2,0
|
||||
brasl %r14,_exit@PLT
|
||||
|
||||
.size make_fcontext,.-make_fcontext
|
||||
.section .note.GNU-stack,"",%progbits
|
163
Zend/asm/make_x86_64_ms_pe_masm.asm
Normal file
163
Zend/asm/make_x86_64_ms_pe_masm.asm
Normal file
|
@ -0,0 +1,163 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; 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)
|
||||
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | limit | base | R12 | R13 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | R14 | R15 | RDI | RSI |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | RBX | RBP | hidden | RIP |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | parameter area |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | FCTX | DATA | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
|
||||
; standard C library function
|
||||
EXTERN _exit:PROC
|
||||
.code
|
||||
|
||||
; generate function table entry in .pdata and unwind information in
|
||||
make_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
|
||||
; .xdata for a function's structured exception handling unwind behavior
|
||||
.endprolog
|
||||
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
mov rax, rcx
|
||||
|
||||
; shift address in RAX to lower 16 byte boundary
|
||||
; == pointer to fcontext_t and address of context stack
|
||||
and rax, -16
|
||||
|
||||
; reserve space for context-data on context-stack
|
||||
; on context-function entry: (RSP -0x8) % 16 == 0
|
||||
sub rax, 0150h
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
; stored in RBX
|
||||
mov [rax+0100h], r8
|
||||
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
; save top address of context stack as 'base'
|
||||
mov [rax+0c8h], rcx
|
||||
; second arg of make_fcontext() == size of context-stack
|
||||
; negate stack size for LEA instruction (== substraction)
|
||||
neg rdx
|
||||
; compute bottom address of context stack (limit)
|
||||
lea rcx, [rcx+rdx]
|
||||
; save bottom address of context stack as 'limit'
|
||||
mov [rax+0c0h], rcx
|
||||
; save address of context stack limit as 'dealloction stack'
|
||||
mov [rax+0b8h], rcx
|
||||
; set fiber-storage to zero
|
||||
xor rcx, rcx
|
||||
mov [rax+0b0h], rcx
|
||||
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [rax+0a0h]
|
||||
; save x87 control-word
|
||||
fnstcw [rax+0a4h]
|
||||
|
||||
; compute address of transport_t
|
||||
lea rcx, [rax+0140h]
|
||||
; store address of transport_t in hidden field
|
||||
mov [rax+0110h], rcx
|
||||
|
||||
; compute abs address of label trampoline
|
||||
lea rcx, trampoline
|
||||
; save address of trampoline as return-address for context-function
|
||||
; will be entered after calling jump_fcontext() first time
|
||||
mov [rax+0118h], rcx
|
||||
|
||||
; compute abs address of label finish
|
||||
lea rcx, finish
|
||||
; save address of finish as return-address for context-function in RBP
|
||||
; will be entered after context-function returns
|
||||
mov [rax+0108h], rcx
|
||||
|
||||
ret ; return pointer to context-data
|
||||
|
||||
trampoline:
|
||||
; store return address on stack
|
||||
; fix stack alignment
|
||||
push rbp
|
||||
; jump to context-function
|
||||
jmp rbx
|
||||
|
||||
finish:
|
||||
; exit code is zero
|
||||
xor rcx, rcx
|
||||
; exit application
|
||||
call _exit
|
||||
hlt
|
||||
make_fcontext ENDP
|
||||
END
|
82
Zend/asm/make_x86_64_sysv_elf_gas.S
Normal file
82
Zend/asm/make_x86_64_sysv_elf_gas.S
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R15 | RBX | RBP | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.file "make_x86_64_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.type make_fcontext,@function
|
||||
.align 16
|
||||
make_fcontext:
|
||||
/* first arg of make_fcontext() == top of context-stack */
|
||||
movq %rdi, %rax
|
||||
|
||||
/* shift address in RAX to lower 16 byte boundary */
|
||||
andq $-16, %rax
|
||||
|
||||
/* reserve space for context-data on context-stack */
|
||||
/* on context-function entry: (RSP -0x8) % 16 == 0 */
|
||||
leaq -0x40(%rax), %rax
|
||||
|
||||
/* third arg of make_fcontext() == address of context-function */
|
||||
/* stored in RBX */
|
||||
movq %rdx, 0x28(%rax)
|
||||
|
||||
/* save MMX control- and status-word */
|
||||
stmxcsr (%rax)
|
||||
/* save x87 control-word */
|
||||
fnstcw 0x4(%rax)
|
||||
|
||||
/* compute abs address of label trampoline */
|
||||
leaq trampoline(%rip), %rcx
|
||||
/* save address of trampoline as return-address for context-function */
|
||||
/* will be entered after calling jump_fcontext() first time */
|
||||
movq %rcx, 0x38(%rax)
|
||||
|
||||
/* compute abs address of label finish */
|
||||
leaq finish(%rip), %rcx
|
||||
/* save address of finish as return-address for context-function */
|
||||
/* will be entered after context-function returns */
|
||||
movq %rcx, 0x30(%rax)
|
||||
|
||||
ret /* return pointer to context-data */
|
||||
|
||||
trampoline:
|
||||
/* store return address on stack */
|
||||
/* fix stack alignment */
|
||||
push %rbp
|
||||
/* jump to context-function */
|
||||
jmp *%rbx
|
||||
|
||||
finish:
|
||||
/* exit code is zero */
|
||||
xorq %rdi, %rdi
|
||||
/* exit application */
|
||||
call _exit@PLT
|
||||
hlt
|
||||
.size make_fcontext,.-make_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
76
Zend/asm/make_x86_64_sysv_macho_gas.S
Normal file
76
Zend/asm/make_x86_64_sysv_macho_gas.S
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
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)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R15 | RBX | RBP | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
.align 8
|
||||
_make_fcontext:
|
||||
/* first arg of make_fcontext() == top of context-stack */
|
||||
movq %rdi, %rax
|
||||
|
||||
/* shift address in RAX to lower 16 byte boundary */
|
||||
andq $-16, %rax
|
||||
|
||||
/* reserve space for context-data on context-stack */
|
||||
/* on context-function entry: (RSP -0x8) % 16 == 0 */
|
||||
leaq -0x40(%rax), %rax
|
||||
|
||||
/* third arg of make_fcontext() == address of context-function */
|
||||
/* stored in RBX */
|
||||
movq %rdx, 0x28(%rax)
|
||||
|
||||
/* save MMX control- and status-word */
|
||||
stmxcsr (%rax)
|
||||
/* save x87 control-word */
|
||||
fnstcw 0x4(%rax)
|
||||
|
||||
/* compute abs address of label trampoline */
|
||||
leaq trampoline(%rip), %rcx
|
||||
/* save address of trampoline as return-address for context-function */
|
||||
/* will be entered after calling jump_fcontext() first time */
|
||||
movq %rcx, 0x38(%rax)
|
||||
|
||||
/* compute abs address of label finish */
|
||||
leaq finish(%rip), %rcx
|
||||
/* save address of finish as return-address for context-function */
|
||||
/* will be entered after context-function returns */
|
||||
movq %rcx, 0x30(%rax)
|
||||
|
||||
ret /* return pointer to context-data */
|
||||
|
||||
trampoline:
|
||||
/* store return address on stack */
|
||||
/* fix stack alignment */
|
||||
push %rbp
|
||||
/* jump to context-function */
|
||||
jmp *%rbx
|
||||
|
||||
finish:
|
||||
/* exit code is zero */
|
||||
xorq %rdi, %rdi
|
||||
/* exit application */
|
||||
call __exit
|
||||
hlt
|
25
Zend/tests/fibers/catch-then-suspend.phpt
Normal file
25
Zend/tests/fibers/catch-then-suspend.phpt
Normal file
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
Catch exception thrown into fiber, then suspend again
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function () {
|
||||
try {
|
||||
Fiber::suspend('in try');
|
||||
} catch (Exception $exception) {
|
||||
}
|
||||
|
||||
Fiber::suspend('after catch');
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
|
||||
var_dump($fiber->throw(new Exception));
|
||||
|
||||
var_dump($fiber->resume());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(6) "in try"
|
||||
string(11) "after catch"
|
||||
NULL
|
22
Zend/tests/fibers/catch.phpt
Normal file
22
Zend/tests/fibers/catch.phpt
Normal file
|
@ -0,0 +1,22 @@
|
|||
--TEST--
|
||||
Catch exception thrown into fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function () {
|
||||
try {
|
||||
Fiber::suspend('test');
|
||||
} catch (Exception $exception) {
|
||||
var_dump($exception->getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
$value = $fiber->start();
|
||||
var_dump($value);
|
||||
|
||||
$fiber->throw(new Exception('test'));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "test"
|
||||
string(4) "test"
|
20
Zend/tests/fibers/double-start.phpt
Normal file
20
Zend/tests/fibers/double-start.phpt
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Start on already running fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
Fiber::suspend();
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
$fiber->start();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot start a fiber that has already been started in %sdouble-start.php:%d
|
||||
Stack trace:
|
||||
#0 %sdouble-start.php(%d): Fiber->start()
|
||||
#1 {main}
|
||||
thrown in %sdouble-start.php on line %d
|
26
Zend/tests/fibers/error-reporting.phpt
Normal file
26
Zend/tests/fibers/error-reporting.phpt
Normal file
|
@ -0,0 +1,26 @@
|
|||
--TEST--
|
||||
Error reporting change reflected inside fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
error_reporting(E_ALL & ~E_USER_NOTICE);
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
trigger_error("Notice A", E_USER_NOTICE); // Should be silenced.
|
||||
Fiber::suspend();
|
||||
trigger_error("Warning A", E_USER_WARNING);
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
trigger_error("Notice B", E_USER_NOTICE); // Should be silenced.
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
trigger_error("Warning B", E_USER_WARNING);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Warning A in %serror-reporting.php on line %d
|
||||
|
||||
Warning: Warning B in %serror-reporting.php on line %d
|
20
Zend/tests/fibers/exit-in-fiber.phpt
Normal file
20
Zend/tests/fibers/exit-in-fiber.phpt
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Exit from fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
Fiber::suspend();
|
||||
echo "resumed\n";
|
||||
exit();
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
echo "unreachable\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
resumed
|
24
Zend/tests/fibers/failing-fiber.phpt
Normal file
24
Zend/tests/fibers/failing-fiber.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Test throwing from fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
Fiber::suspend('test');
|
||||
throw new Exception('test');
|
||||
});
|
||||
|
||||
$value = $fiber->start();
|
||||
var_dump($value);
|
||||
|
||||
$fiber->resume($value);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(4) "test"
|
||||
|
||||
Fatal error: Uncaught Exception: test in %sfailing-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure}()
|
||||
#1 {main}
|
||||
thrown in %sfailing-fiber.php on line %d
|
17
Zend/tests/fibers/fast-finish-fiber.phpt
Normal file
17
Zend/tests/fibers/fast-finish-fiber.phpt
Normal file
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
Fast finishing fiber does not leak
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => 'test');
|
||||
var_dump($fiber->isStarted());
|
||||
var_dump($fiber->start());
|
||||
var_dump($fiber->getReturn());
|
||||
var_dump($fiber->isTerminated());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
NULL
|
||||
string(4) "test"
|
||||
bool(true)
|
14
Zend/tests/fibers/fatal-error-in-fiber.phpt
Normal file
14
Zend/tests/fibers/fatal-error-in-fiber.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
Fatal error in new fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
trigger_error("Fatal error in fiber", E_USER_ERROR);
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Fatal error in fiber in %sfatal-error-in-fiber.php on line %d
|
28
Zend/tests/fibers/fatal-error-in-nested-fiber.phpt
Normal file
28
Zend/tests/fibers/fatal-error-in-nested-fiber.phpt
Normal file
|
@ -0,0 +1,28 @@
|
|||
--TEST--
|
||||
Fatal error within a nested fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
$fiber = new Fiber(function (): void {
|
||||
\Fiber::suspend(2);
|
||||
trigger_error("Fatal error in nested fiber", E_USER_ERROR);
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
|
||||
\Fiber::suspend(1);
|
||||
|
||||
$fiber->resume();
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(2)
|
||||
int(1)
|
||||
|
||||
Fatal error: Fatal error in nested fiber in %sfatal-error-in-nested-fiber.php on line %d
|
28
Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt
Normal file
28
Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt
Normal file
|
@ -0,0 +1,28 @@
|
|||
--TEST--
|
||||
Fatal error in a fiber with other active fibers
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber1 = new Fiber(function (): void {
|
||||
try {
|
||||
\Fiber::suspend(1);
|
||||
} finally {
|
||||
echo "not executed";
|
||||
}
|
||||
});
|
||||
|
||||
$fiber2 = new Fiber(function (): void {
|
||||
\Fiber::suspend(2);
|
||||
trigger_error("Fatal error in fiber", E_USER_ERROR);
|
||||
});
|
||||
|
||||
var_dump($fiber1->start());
|
||||
var_dump($fiber2->start());
|
||||
$fiber2->resume();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
int(2)
|
||||
|
||||
Fatal error: Fatal error in fiber in %sfatal-error-with-multiple-fibers.php on line %d
|
43
Zend/tests/fibers/fiber-created-during-cleanup.phpt
Normal file
43
Zend/tests/fibers/fiber-created-during-cleanup.phpt
Normal file
|
@ -0,0 +1,43 @@
|
|||
--TEST--
|
||||
Fibers created during cleanup
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fibers = [];
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$fibers[$i] = new Fiber(function() {
|
||||
try {
|
||||
Fiber::suspend();
|
||||
} finally {
|
||||
echo "finally\n";
|
||||
$fiber2 = new Fiber(function() {
|
||||
echo "new\n";
|
||||
try {
|
||||
Fiber::suspend();
|
||||
} finally {
|
||||
echo "new finally\n";
|
||||
}
|
||||
});
|
||||
$fiber2->start();
|
||||
}
|
||||
});
|
||||
$fibers[$i]->start();
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
finally
|
||||
new
|
||||
new finally
|
||||
finally
|
||||
new
|
||||
new finally
|
||||
finally
|
||||
new
|
||||
new finally
|
||||
finally
|
||||
new
|
||||
new finally
|
||||
finally
|
||||
new
|
||||
new finally
|
24
Zend/tests/fibers/fiber-created-in-destruct.phpt
Normal file
24
Zend/tests/fibers/fiber-created-in-destruct.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Fiber created in destructor
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$object = new class() {
|
||||
public function __destruct()
|
||||
{
|
||||
$fiber = new Fiber(static function (): int {
|
||||
Fiber::suspend(1);
|
||||
return 2;
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
var_dump($fiber->resume());
|
||||
var_dump($fiber->getReturn());
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
NULL
|
||||
int(2)
|
14
Zend/tests/fibers/fiber-error-construct.phpt
Normal file
14
Zend/tests/fibers/fiber-error-construct.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
FiberError cannot be constructed in user code
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
new FiberError;
|
||||
} catch (Error $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
The "FiberError" class is reserved for internal use and cannot be manually instantiated
|
35
Zend/tests/fibers/fiber-in-destruct.phpt
Normal file
35
Zend/tests/fibers/fiber-in-destruct.phpt
Normal file
|
@ -0,0 +1,35 @@
|
|||
--TEST--
|
||||
Pause fiber in destruct
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): int {
|
||||
$object = new class() {
|
||||
public function __destruct()
|
||||
{
|
||||
Fiber::suspend(2);
|
||||
}
|
||||
};
|
||||
|
||||
Fiber::suspend(1);
|
||||
|
||||
unset($object);
|
||||
|
||||
Fiber::suspend(3);
|
||||
|
||||
return 4;
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
var_dump($fiber->resume());
|
||||
var_dump($fiber->resume());
|
||||
var_dump($fiber->resume());
|
||||
var_dump($fiber->getReturn());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
NULL
|
||||
int(4)
|
24
Zend/tests/fibers/fiber-in-shutdown-function.phpt
Normal file
24
Zend/tests/fibers/fiber-in-shutdown-function.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Fiber in shutdown function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
register_shutdown_function(function (): void {
|
||||
$fiber = new Fiber(function (): int {
|
||||
Fiber::suspend(1);
|
||||
Fiber::suspend(2);
|
||||
return 3;
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
var_dump($fiber->resume());
|
||||
var_dump($fiber->resume());
|
||||
var_dump($fiber->getReturn());
|
||||
});
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(2)
|
||||
NULL
|
||||
int(3)
|
62
Zend/tests/fibers/fiber-status.phpt
Normal file
62
Zend/tests/fibers/fiber-status.phpt
Normal file
|
@ -0,0 +1,62 @@
|
|||
--TEST--
|
||||
Fiber status methods
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
$fiber = Fiber::this();
|
||||
echo "\nWithin Fiber:\n";
|
||||
var_dump($fiber->isStarted());
|
||||
var_dump($fiber->isRunning());
|
||||
var_dump($fiber->isSuspended());
|
||||
var_dump($fiber->isTerminated());
|
||||
Fiber::suspend();
|
||||
});
|
||||
|
||||
echo "\nBefore Start:\n";
|
||||
var_dump($fiber->isStarted());
|
||||
var_dump($fiber->isRunning());
|
||||
var_dump($fiber->isSuspended());
|
||||
var_dump($fiber->isTerminated());
|
||||
|
||||
$fiber->start();
|
||||
|
||||
echo "\nAfter Start:\n";
|
||||
var_dump($fiber->isStarted());
|
||||
var_dump($fiber->isRunning());
|
||||
var_dump($fiber->isSuspended());
|
||||
var_dump($fiber->isTerminated());
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
echo "\nAfter Resume:\n";
|
||||
var_dump($fiber->isStarted());
|
||||
var_dump($fiber->isRunning());
|
||||
var_dump($fiber->isSuspended());
|
||||
var_dump($fiber->isTerminated());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Before Start:
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
|
||||
Within Fiber:
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
|
||||
After Start:
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
|
||||
After Resume:
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(true)
|
18
Zend/tests/fibers/fiber-this.phpt
Normal file
18
Zend/tests/fibers/fiber-this.phpt
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Fiber::this()
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(Fiber::this());
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
var_dump(Fiber::this());
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
NULL
|
||||
object(Fiber)#%d (0) {
|
||||
}
|
27
Zend/tests/fibers/fiber-throw-in-destruct.phpt
Normal file
27
Zend/tests/fibers/fiber-throw-in-destruct.phpt
Normal file
|
@ -0,0 +1,27 @@
|
|||
--TEST--
|
||||
Fiber throwing from destructor
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$object = new class() {
|
||||
public function __destruct()
|
||||
{
|
||||
$fiber = new Fiber(static function (): int {
|
||||
Fiber::suspend(1);
|
||||
throw new Exception('test');
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
var_dump($fiber->resume());
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
|
||||
Fatal error: Uncaught Exception: test in %sfiber-throw-in-destruct.php:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: class@anonymous::{closure}()
|
||||
#1 {main}
|
||||
thrown in %sfiber-throw-in-destruct.php on line %d
|
24
Zend/tests/fibers/get-return-after-throwing.phpt
Normal file
24
Zend/tests/fibers/get-return-after-throwing.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Fiber::getReturn() after a fiber throws
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => throw new Exception('test'));
|
||||
|
||||
try {
|
||||
$fiber->start();
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
|
||||
$fiber->getReturn();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
test
|
||||
|
||||
Fatal error: Uncaught FiberError: Cannot get fiber return value: The fiber threw an exception in %sget-return-after-throwing.php:%d
|
||||
Stack trace:
|
||||
#0 %sget-return-after-throwing.php(%d): Fiber->getReturn()
|
||||
#1 {main}
|
||||
thrown in %sget-return-after-throwing.php on line %d
|
16
Zend/tests/fibers/get-return-from-unstarted-fiber.phpt
Normal file
16
Zend/tests/fibers/get-return-from-unstarted-fiber.phpt
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
Fiber::getReturn() from unstarted fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => Fiber::suspend(1));
|
||||
|
||||
$fiber->getReturn();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot get fiber return value: The fiber has not been started in %sget-return-from-unstarted-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sget-return-from-unstarted-fiber.php(%d): Fiber->getReturn()
|
||||
#1 {main}
|
||||
thrown in %sget-return-from-unstarted-fiber.php on line %d
|
20
Zend/tests/fibers/get-return-in-unfinished-fiber.phpt
Normal file
20
Zend/tests/fibers/get-return-in-unfinished-fiber.phpt
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Fiber::getReturn() in unfinished fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => Fiber::suspend(1));
|
||||
|
||||
var_dump($fiber->start());
|
||||
|
||||
$fiber->getReturn();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
|
||||
Fatal error: Uncaught FiberError: Cannot get fiber return value: The fiber has not returned in %sget-return-in-unfinished-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sget-return-in-unfinished-fiber.php(%d): Fiber->getReturn()
|
||||
#1 {main}
|
||||
thrown in %sget-return-in-unfinished-fiber.php on line %d
|
20
Zend/tests/fibers/get-return.phpt
Normal file
20
Zend/tests/fibers/get-return.phpt
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Test fiber return value
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): string {
|
||||
$value = Fiber::suspend("x");
|
||||
return $value;
|
||||
});
|
||||
|
||||
$value = $fiber->start();
|
||||
var_dump($value);
|
||||
var_dump($fiber->resume($value . "y"));
|
||||
var_dump($fiber->getReturn());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "x"
|
||||
NULL
|
||||
string(2) "xy"
|
27
Zend/tests/fibers/invocable-class.phpt
Normal file
27
Zend/tests/fibers/invocable-class.phpt
Normal file
|
@ -0,0 +1,27 @@
|
|||
--TEST--
|
||||
Reference to invocable class retained while running
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
public function __invoke() {
|
||||
$GLOBALS['test'] = null;
|
||||
var_dump($this);
|
||||
try {
|
||||
Fiber::suspend();
|
||||
} finally {
|
||||
var_dump($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$test = new Test;
|
||||
$fiber = new Fiber($test);
|
||||
$fiber->start();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
object(Test)#1 (0) {
|
||||
}
|
||||
object(Test)#1 (0) {
|
||||
}
|
16
Zend/tests/fibers/resume-non-running-fiber.phpt
Normal file
16
Zend/tests/fibers/resume-non-running-fiber.phpt
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
Resume non-running fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => null);
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot resume a fiber that is not suspended in %sresume-non-running-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sresume-non-running-fiber.php(%d): Fiber->resume()
|
||||
#1 {main}
|
||||
thrown in %sresume-non-running-fiber.php on line %d
|
20
Zend/tests/fibers/resume-running-fiber.phpt
Normal file
20
Zend/tests/fibers/resume-running-fiber.phpt
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Resume running fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
$self = Fiber::this();
|
||||
$self->resume();
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot resume a fiber that is not suspended in %sresume-running-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sresume-running-fiber.php(%d): Fiber->resume()
|
||||
#1 [internal function]: {closure}()
|
||||
#2 {main}
|
||||
thrown in %sresume-running-fiber.php on line %d
|
18
Zend/tests/fibers/resume-terminated-fiber.phpt
Normal file
18
Zend/tests/fibers/resume-terminated-fiber.phpt
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Resume terminated fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => null);
|
||||
|
||||
$fiber->start();
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot resume a fiber that is not suspended in %sresume-terminated-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sresume-terminated-fiber.php(%d): Fiber->resume()
|
||||
#1 {main}
|
||||
thrown in %sresume-terminated-fiber.php on line %d
|
18
Zend/tests/fibers/resume.phpt
Normal file
18
Zend/tests/fibers/resume.phpt
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Test resume
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
$value = Fiber::suspend(1);
|
||||
var_dump($value);
|
||||
});
|
||||
|
||||
$value = $fiber->start();
|
||||
var_dump($value);
|
||||
$fiber->resume($value + 1);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(2)
|
28
Zend/tests/fibers/silence-operator-inside-fiber.phpt
Normal file
28
Zend/tests/fibers/silence-operator-inside-fiber.phpt
Normal file
|
@ -0,0 +1,28 @@
|
|||
--TEST--
|
||||
Silence operator does not leak out of fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function suspend_with_warnings(): void {
|
||||
trigger_error("Warning A", E_USER_WARNING); // Should be silenced.
|
||||
Fiber::suspend();
|
||||
trigger_error("Warning B", E_USER_WARNING); // Should be silenced.
|
||||
}
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
@suspend_with_warnings();
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
trigger_error("Warning C", E_USER_WARNING);
|
||||
|
||||
$fiber->resume();
|
||||
|
||||
trigger_error("Warning D", E_USER_WARNING);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Warning C in %ssilence-operator-inside-fiber.php on line %d
|
||||
|
||||
Warning: Warning D in %ssilence-operator-inside-fiber.php on line %d
|
28
Zend/tests/fibers/silence-operator-outside-fiber.phpt
Normal file
28
Zend/tests/fibers/silence-operator-outside-fiber.phpt
Normal file
|
@ -0,0 +1,28 @@
|
|||
--TEST--
|
||||
Silence operator does not leak into fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = @new Fiber(function (): void {
|
||||
trigger_error("Warning A", E_USER_WARNING);
|
||||
Fiber::suspend();
|
||||
trigger_error("Warning C", E_USER_WARNING);
|
||||
});
|
||||
|
||||
@$fiber->start();
|
||||
|
||||
trigger_error("Warning B", E_USER_WARNING);
|
||||
|
||||
@$fiber->resume();
|
||||
|
||||
trigger_error("Warning D", E_USER_WARNING);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Warning A in %ssilence-operator-outside-fiber.php on line %d
|
||||
|
||||
Warning: Warning B in %ssilence-operator-outside-fiber.php on line %d
|
||||
|
||||
Warning: Warning C in %ssilence-operator-outside-fiber.php on line %d
|
||||
|
||||
Warning: Warning D in %ssilence-operator-outside-fiber.php on line %d
|
28
Zend/tests/fibers/start-arguments.phpt
Normal file
28
Zend/tests/fibers/start-arguments.phpt
Normal file
|
@ -0,0 +1,28 @@
|
|||
--TEST--
|
||||
Arguments to fiber callback
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (int $x): int {
|
||||
return $x + Fiber::suspend($x);
|
||||
});
|
||||
|
||||
$x = $fiber->start(1);
|
||||
$fiber->resume(0);
|
||||
var_dump($fiber->getReturn());
|
||||
|
||||
$fiber = new Fiber(function (int $x): int {
|
||||
return $x + Fiber::suspend($x);
|
||||
});
|
||||
|
||||
$fiber->start('test');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
|
||||
Fatal error: Uncaught TypeError: {closure}(): Argument #1 ($x) must be of type int, string given in %sstart-arguments.php:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure}('test')
|
||||
#1 {main}
|
||||
thrown in %sstart-arguments.php on line %d
|
|
@ -0,0 +1,27 @@
|
|||
--TEST--
|
||||
Suspend in force closed fiber after shutdown
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
try {
|
||||
Fiber::suspend();
|
||||
} finally {
|
||||
Fiber::suspend();
|
||||
}
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
done
|
||||
|
||||
Fatal error: Uncaught FiberError: Cannot suspend in a force closed fiber in %ssuspend-in-force-close-fiber-after-shutdown.php:%d
|
||||
Stack trace:
|
||||
#0 %ssuspend-in-force-close-fiber-after-shutdown.php(%d): Fiber::suspend()
|
||||
#1 [internal function]: {closure}()
|
||||
#2 {main}
|
||||
thrown in %ssuspend-in-force-close-fiber-after-shutdown.php on line %d
|
25
Zend/tests/fibers/suspend-in-force-close-fiber.phpt
Normal file
25
Zend/tests/fibers/suspend-in-force-close-fiber.phpt
Normal file
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
Suspend in force closed fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
try {
|
||||
Fiber::suspend();
|
||||
} finally {
|
||||
Fiber::suspend();
|
||||
}
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
unset($fiber);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot suspend in a force closed fiber in %ssuspend-in-force-close-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %ssuspend-in-force-close-fiber.php(%d): Fiber::suspend()
|
||||
#1 [internal function]: {closure}()
|
||||
#2 {main}
|
||||
thrown in %ssuspend-in-force-close-fiber.php on line %d
|
29
Zend/tests/fibers/suspend-in-nested-function.phpt
Normal file
29
Zend/tests/fibers/suspend-in-nested-function.phpt
Normal file
|
@ -0,0 +1,29 @@
|
|||
--TEST--
|
||||
Suspend within nested function call
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function suspend(): int
|
||||
{
|
||||
return Fiber::suspend(1);
|
||||
}
|
||||
|
||||
$fiber = new Fiber(function (): int {
|
||||
$value = suspend();
|
||||
return Fiber::suspend($value);
|
||||
});
|
||||
|
||||
var_dump($fiber->start());
|
||||
var_dump($fiber->resume(2));
|
||||
var_dump($fiber->resume(3));
|
||||
var_dump($fiber->getReturn());
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(2)
|
||||
NULL
|
||||
int(3)
|
||||
done
|
14
Zend/tests/fibers/suspend-outside-fiber.phpt
Normal file
14
Zend/tests/fibers/suspend-outside-fiber.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
Suspend outside fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$value = Fiber::suspend(1);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot suspend outside of a fiber in %ssuspend-outside-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %ssuspend-outside-fiber.php(%d): Fiber::suspend(1)
|
||||
#1 {main}
|
||||
thrown in %ssuspend-outside-fiber.php on line %d
|
22
Zend/tests/fibers/throw-from-destruct-with-fiber.phpt
Normal file
22
Zend/tests/fibers/throw-from-destruct-with-fiber.phpt
Normal file
|
@ -0,0 +1,22 @@
|
|||
--TEST--
|
||||
Test destructor throwing with unfinished fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
new class() {
|
||||
function __destruct() {
|
||||
$fiber = new Fiber(static function() {
|
||||
Fiber::suspend();
|
||||
});
|
||||
$fiber->start();
|
||||
throw new Exception;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Exception in %sthrow-from-destruct-with-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sthrow-from-destruct-with-fiber.php(%d): class@anonymous->__destruct()
|
||||
#1 {main}
|
||||
thrown in %sthrow-from-destruct-with-fiber.php on line %d
|
16
Zend/tests/fibers/throw-into-non-running-fiber.phpt
Normal file
16
Zend/tests/fibers/throw-into-non-running-fiber.phpt
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
Throw into non-running fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => null);
|
||||
|
||||
$fiber->throw(new Exception('test'));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught FiberError: Cannot resume a fiber that is not suspended in %sthrow-into-non-running-fiber.php:%d
|
||||
Stack trace:
|
||||
#0 %sthrow-into-non-running-fiber.php(%d): Fiber->throw(Object(Exception))
|
||||
#1 {main}
|
||||
thrown in %sthrow-into-non-running-fiber.php on line %d
|
22
Zend/tests/fibers/throw.phpt
Normal file
22
Zend/tests/fibers/throw.phpt
Normal file
|
@ -0,0 +1,22 @@
|
|||
--TEST--
|
||||
Test throwing into fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
Fiber::suspend('test');
|
||||
});
|
||||
|
||||
$value = $fiber->start();
|
||||
var_dump($value);
|
||||
|
||||
$fiber->throw(new Exception('test'));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(4) "test"
|
||||
|
||||
Fatal error: Uncaught Exception: test in %sthrow.php:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %sthrow.php on line %d
|
30
Zend/tests/fibers/unfinished-fiber-with-finally.phpt
Normal file
30
Zend/tests/fibers/unfinished-fiber-with-finally.phpt
Normal file
|
@ -0,0 +1,30 @@
|
|||
--TEST--
|
||||
Test unfinished fiber with finally block
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
try {
|
||||
echo "fiber\n";
|
||||
echo Fiber::suspend();
|
||||
echo "after suspend\n";
|
||||
} catch (Throwable $exception) {
|
||||
echo "exit exception caught!\n";
|
||||
} finally {
|
||||
echo "finally\n";
|
||||
}
|
||||
|
||||
echo "end of fiber should not be reached\n";
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
unset($fiber); // Destroy fiber object, executing finally block.
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
fiber
|
||||
finally
|
||||
done
|
|
@ -0,0 +1,47 @@
|
|||
--TEST--
|
||||
Test unfinished fiber with nested try/catch blocks
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
echo "fiber\n";
|
||||
echo Fiber::suspend();
|
||||
echo "after await\n";
|
||||
} catch (Throwable $exception) {
|
||||
echo "inner exit exception caught!\n";
|
||||
}
|
||||
} catch (Throwable $exception) {
|
||||
echo "exit exception caught!\n";
|
||||
} finally {
|
||||
echo "inner finally\n";
|
||||
}
|
||||
} finally {
|
||||
echo "outer finally\n";
|
||||
}
|
||||
|
||||
echo "unreached\n";
|
||||
|
||||
try {
|
||||
echo Fiber::suspend();
|
||||
} finally {
|
||||
echo "unreached\n";
|
||||
}
|
||||
|
||||
echo "end of fiber should not be reached\n";
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
unset($fiber); // Destroy fiber object, executing finally block.
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
fiber
|
||||
inner finally
|
||||
outer finally
|
||||
done
|
|
@ -0,0 +1,36 @@
|
|||
--TEST--
|
||||
Test unfinished fiber with suspend in finally
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): object {
|
||||
try {
|
||||
try {
|
||||
echo "fiber\n";
|
||||
return new \stdClass;
|
||||
} finally {
|
||||
echo "inner finally\n";
|
||||
Fiber::suspend();
|
||||
echo "after await\n";
|
||||
}
|
||||
} catch (Throwable $exception) {
|
||||
echo "exit exception caught!\n";
|
||||
} finally {
|
||||
echo "outer finally\n";
|
||||
}
|
||||
|
||||
echo "end of fiber should not be reached\n";
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
unset($fiber); // Destroy fiber object, executing finally block.
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
fiber
|
||||
inner finally
|
||||
outer finally
|
||||
done
|
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
Test unfinished fiber with suspend in finally
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
echo "fiber\n";
|
||||
echo Fiber::suspend();
|
||||
echo "after await\n";
|
||||
} catch (Throwable $exception) {
|
||||
echo "inner exit exception caught!\n";
|
||||
}
|
||||
} catch (Throwable $exception) {
|
||||
echo "exit exception caught!\n";
|
||||
} finally {
|
||||
echo "inner finally\n";
|
||||
throw new \Exception("finally exception");
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
} finally {
|
||||
echo "outer finally\n";
|
||||
}
|
||||
|
||||
try {
|
||||
echo Fiber::suspend();
|
||||
} catch (FiberError $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
unset($fiber); // Destroy fiber object, executing finally block.
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
fiber
|
||||
inner finally
|
||||
finally exception
|
||||
outer finally
|
||||
Cannot suspend in a force closed fiber
|
||||
done
|
25
Zend/tests/fibers/unfinished-fiber.phpt
Normal file
25
Zend/tests/fibers/unfinished-fiber.phpt
Normal file
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
Test unfinished fiber
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(function (): void {
|
||||
try {
|
||||
echo "fiber\n";
|
||||
echo Fiber::suspend();
|
||||
echo "after suspend\n";
|
||||
} catch (Throwable $exception) {
|
||||
echo "exit exception caught!\n";
|
||||
}
|
||||
|
||||
echo "end of fiber should not be reached\n";
|
||||
});
|
||||
|
||||
$fiber->start();
|
||||
|
||||
echo "done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
fiber
|
||||
done
|
12
Zend/tests/fibers/unstarted-fiber.phpt
Normal file
12
Zend/tests/fibers/unstarted-fiber.phpt
Normal file
|
@ -0,0 +1,12 @@
|
|||
--TEST--
|
||||
Not starting a fiber does not leak
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$fiber = new Fiber(fn() => null);
|
||||
|
||||
echo "done";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
done
|
21
Zend/zend.c
21
Zend/zend.c
|
@ -34,6 +34,7 @@
|
|||
#include "zend_cpuinfo.h"
|
||||
#include "zend_attributes.h"
|
||||
#include "zend_observer.h"
|
||||
#include "zend_fibers.h"
|
||||
#include "Optimizer/zend_optimizer.h"
|
||||
|
||||
static size_t global_map_ptr_last = 0;
|
||||
|
@ -174,6 +175,17 @@ static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static ZEND_INI_MH(OnUpdateFiberStackSize) /* {{{ */
|
||||
{
|
||||
if (new_value) {
|
||||
EG(fiber_stack_size) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
|
||||
} else {
|
||||
EG(fiber_stack_size) = ZEND_FIBER_DEFAULT_C_STACK_SIZE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if ZEND_DEBUG
|
||||
# define SIGNAL_CHECK_DEFAULT "1"
|
||||
#else
|
||||
|
@ -192,6 +204,8 @@ ZEND_INI_BEGIN()
|
|||
#endif
|
||||
STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
|
||||
STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals)
|
||||
STD_ZEND_INI_ENTRY("fiber.stack_size", NULL, ZEND_INI_ALL, OnUpdateFiberStackSize, fiber_stack_size, zend_executor_globals, executor_globals)
|
||||
|
||||
ZEND_INI_END()
|
||||
|
||||
ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
|
||||
|
@ -759,6 +773,8 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
|
|||
executor_globals->exception_class = NULL;
|
||||
executor_globals->exception = NULL;
|
||||
executor_globals->objects_store.object_buckets = NULL;
|
||||
executor_globals->current_fiber = NULL;
|
||||
executor_globals->fiber_error = NULL;
|
||||
#ifdef ZEND_WIN32
|
||||
zend_get_windows_version_info(&executor_globals->windows_version_info);
|
||||
#endif
|
||||
|
@ -1327,6 +1343,11 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
|
|||
zend_stack delayed_oplines_stack;
|
||||
int type = orig_type & E_ALL;
|
||||
|
||||
/* Fatal errors must be handled in {main} */
|
||||
if (type & E_FATAL_ERRORS && EG(current_fiber)) {
|
||||
zend_error_suspend_fiber(orig_type, error_filename, error_lineno, message);
|
||||
}
|
||||
|
||||
/* If we're executing a function during SCCP, count any warnings that may be emitted,
|
||||
* but don't perform any other error handling. */
|
||||
if (EG(capture_warnings_during_sccp)) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "zend_generators.h"
|
||||
#include "zend_weakrefs.h"
|
||||
#include "zend_enum.h"
|
||||
#include "zend_fibers.h"
|
||||
|
||||
ZEND_API void zend_register_default_classes(void)
|
||||
{
|
||||
|
@ -38,4 +39,5 @@ ZEND_API void zend_register_default_classes(void)
|
|||
zend_register_weakref_ce();
|
||||
zend_register_attribute_ce();
|
||||
zend_register_enum_ce();
|
||||
zend_register_fiber_ce();
|
||||
}
|
||||
|
|
|
@ -43,9 +43,12 @@ ZEND_API zend_class_entry *zend_ce_arithmetic_error;
|
|||
ZEND_API zend_class_entry *zend_ce_division_by_zero_error;
|
||||
ZEND_API zend_class_entry *zend_ce_unhandled_match_error;
|
||||
|
||||
/* Internal pseudo-exception that is not exposed to userland. */
|
||||
/* Internal pseudo-exception that is not exposed to userland. Throwing this exception *does not* execute finally blocks. */
|
||||
static zend_class_entry zend_ce_unwind_exit;
|
||||
|
||||
/* Internal pseudo-exception that is not exposed to userland. Throwing this exception *does* execute finally blocks. */
|
||||
static zend_class_entry zend_ce_graceful_exit;
|
||||
|
||||
ZEND_API void (*zend_throw_exception_hook)(zend_object *ex);
|
||||
|
||||
static zend_object_handlers default_exception_handlers;
|
||||
|
@ -94,7 +97,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
|
|||
return;
|
||||
}
|
||||
|
||||
if (exception == add_previous || zend_is_unwind_exit(add_previous)) {
|
||||
if (exception == add_previous || zend_is_unwind_exit(add_previous) || zend_is_graceful_exit(add_previous)) {
|
||||
OBJ_RELEASE(add_previous);
|
||||
return;
|
||||
}
|
||||
|
@ -791,6 +794,8 @@ void zend_register_default_exception(void) /* {{{ */
|
|||
zend_ce_unhandled_match_error->create_object = zend_default_exception_new;
|
||||
|
||||
INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL);
|
||||
|
||||
INIT_CLASS_ENTRY(zend_ce_graceful_exit, "GracefulExit", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -949,7 +954,7 @@ ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *ex, int severit
|
|||
|
||||
zend_string_release_ex(str, 0);
|
||||
zend_string_release_ex(file, 0);
|
||||
} else if (ce_exception == &zend_ce_unwind_exit) {
|
||||
} else if (ce_exception == &zend_ce_unwind_exit || ce_exception == &zend_ce_graceful_exit) {
|
||||
/* We successfully unwound, nothing more to do.
|
||||
* We still return FAILURE in this case, as further execution should still be aborted. */
|
||||
} else {
|
||||
|
@ -987,7 +992,20 @@ ZEND_API ZEND_COLD void zend_throw_unwind_exit(void)
|
|||
EG(current_execute_data)->opline = EG(exception_op);
|
||||
}
|
||||
|
||||
ZEND_API bool zend_is_unwind_exit(zend_object *ex)
|
||||
ZEND_API ZEND_COLD void zend_throw_graceful_exit(void)
|
||||
{
|
||||
ZEND_ASSERT(!EG(exception));
|
||||
EG(exception) = zend_objects_new(&zend_ce_graceful_exit);
|
||||
EG(opline_before_exception) = EG(current_execute_data)->opline;
|
||||
EG(current_execute_data)->opline = EG(exception_op);
|
||||
}
|
||||
|
||||
ZEND_API bool zend_is_unwind_exit(const zend_object *ex)
|
||||
{
|
||||
return ex->ce == &zend_ce_unwind_exit;
|
||||
}
|
||||
|
||||
ZEND_API bool zend_is_graceful_exit(const zend_object *ex)
|
||||
{
|
||||
return ex->ce == &zend_ce_graceful_exit;
|
||||
}
|
||||
|
|
|
@ -70,7 +70,9 @@ extern ZEND_API void (*zend_throw_exception_hook)(zend_object *ex);
|
|||
ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *exception, int severity);
|
||||
|
||||
ZEND_API ZEND_COLD void zend_throw_unwind_exit(void);
|
||||
ZEND_API bool zend_is_unwind_exit(zend_object *ex);
|
||||
ZEND_API ZEND_COLD void zend_throw_graceful_exit(void);
|
||||
ZEND_API bool zend_is_unwind_exit(const zend_object *ex);
|
||||
ZEND_API bool zend_is_graceful_exit(const zend_object *ex);
|
||||
|
||||
#include "zend_globals.h"
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "zend_generators.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_float.h"
|
||||
#include "zend_fibers.h"
|
||||
#include "zend_weakrefs.h"
|
||||
#include "zend_inheritance.h"
|
||||
#include "zend_observer.h"
|
||||
|
@ -187,6 +188,7 @@ void init_executor(void) /* {{{ */
|
|||
|
||||
EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL;
|
||||
|
||||
zend_fiber_init();
|
||||
zend_weakrefs_init();
|
||||
|
||||
EG(active) = 1;
|
||||
|
|
698
Zend/zend_fibers.c
Normal file
698
Zend/zend_fibers.c
Normal file
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Aaron Piotrowski <aaron@trowski.com> |
|
||||
| Martin Schröder <m.schroeder2007@gmail.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_ini.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_interfaces.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_builtin_functions.h"
|
||||
#include "zend_observer.h"
|
||||
|
||||
#include "zend_fibers.h"
|
||||
#include "zend_fibers_arginfo.h"
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
# include <valgrind/valgrind.h>
|
||||
#endif
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
# include <unistd.h>
|
||||
# include <sys/mman.h>
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
ZEND_API zend_class_entry *zend_ce_fiber;
|
||||
static zend_class_entry *zend_ce_fiber_error;
|
||||
|
||||
static zend_object_handlers zend_fiber_handlers;
|
||||
|
||||
typedef void *fcontext_t;
|
||||
|
||||
typedef struct _transfer_t {
|
||||
fcontext_t context;
|
||||
void *data;
|
||||
} transfer_t;
|
||||
|
||||
extern fcontext_t make_fcontext(void *sp, size_t size, void (*fn)(transfer_t));
|
||||
extern transfer_t jump_fcontext(fcontext_t to, void *vp);
|
||||
|
||||
#define ZEND_FIBER_DEFAULT_PAGE_SIZE 4096
|
||||
|
||||
#define ZEND_FIBER_BACKUP_EG(stack, stack_page_size, execute_data, error_reporting, trace_num) do { \
|
||||
stack = EG(vm_stack); \
|
||||
stack->top = EG(vm_stack_top); \
|
||||
stack->end = EG(vm_stack_end); \
|
||||
stack_page_size = EG(vm_stack_page_size); \
|
||||
execute_data = EG(current_execute_data); \
|
||||
error_reporting = EG(error_reporting); \
|
||||
trace_num = EG(jit_trace_num); \
|
||||
} while (0)
|
||||
|
||||
#define ZEND_FIBER_RESTORE_EG(stack, stack_page_size, execute_data, error_reporting, trace_num) do { \
|
||||
EG(vm_stack) = stack; \
|
||||
EG(vm_stack_top) = stack->top; \
|
||||
EG(vm_stack_end) = stack->end; \
|
||||
EG(vm_stack_page_size) = stack_page_size; \
|
||||
EG(current_execute_data) = execute_data; \
|
||||
EG(error_reporting) = error_reporting; \
|
||||
EG(jit_trace_num) = trace_num; \
|
||||
} while (0)
|
||||
|
||||
#if defined(MAP_STACK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
|
||||
# define ZEND_FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON | MAP_STACK)
|
||||
#else
|
||||
# define ZEND_FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static size_t zend_fiber_page_size()
|
||||
{
|
||||
#if _POSIX_MAPPED_FILES
|
||||
static size_t page_size;
|
||||
|
||||
if (!page_size) {
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
return page_size;
|
||||
#else
|
||||
return ZEND_FIBER_DEFAULT_PAGE_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool zend_fiber_stack_allocate(zend_fiber_stack *stack, size_t size)
|
||||
{
|
||||
void *pointer;
|
||||
const size_t page_size = zend_fiber_page_size();
|
||||
|
||||
ZEND_ASSERT(size >= page_size + ZEND_FIBER_GUARD_PAGES * page_size);
|
||||
|
||||
stack->size = (size + page_size - 1) / page_size * page_size;
|
||||
const size_t msize = stack->size + ZEND_FIBER_GUARD_PAGES * page_size;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
pointer = VirtualAlloc(0, msize, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
if (!pointer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
# if ZEND_FIBER_GUARD_PAGES
|
||||
DWORD protect;
|
||||
|
||||
if (!VirtualProtect(pointer, ZEND_FIBER_GUARD_PAGES * page_size, PAGE_READWRITE | PAGE_GUARD, &protect)) {
|
||||
VirtualFree(pointer, 0, MEM_RELEASE);
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
pointer = mmap(NULL, msize, PROT_READ | PROT_WRITE, ZEND_FIBER_STACK_FLAGS, -1, 0);
|
||||
|
||||
if (pointer == MAP_FAILED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
# if ZEND_FIBER_GUARD_PAGES
|
||||
if (mprotect(pointer, ZEND_FIBER_GUARD_PAGES * page_size, PROT_NONE) < 0) {
|
||||
munmap(pointer, msize);
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
stack->pointer = (void *) ((uintptr_t) pointer + ZEND_FIBER_GUARD_PAGES * page_size);
|
||||
|
||||
#ifdef VALGRIND_STACK_REGISTER
|
||||
uintptr_t base = (uintptr_t) stack->pointer;
|
||||
stack->valgrind = VALGRIND_STACK_REGISTER(base, base + stack->size);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void zend_fiber_stack_free(zend_fiber_stack *stack)
|
||||
{
|
||||
if (!stack->pointer) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef VALGRIND_STACK_DEREGISTER
|
||||
VALGRIND_STACK_DEREGISTER(stack->valgrind);
|
||||
#endif
|
||||
|
||||
const size_t page_size = zend_fiber_page_size();
|
||||
|
||||
void *pointer = (void *) ((uintptr_t) stack->pointer - ZEND_FIBER_GUARD_PAGES * page_size);
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
VirtualFree(pointer, 0, MEM_RELEASE);
|
||||
#else
|
||||
munmap(pointer, stack->size + ZEND_FIBER_GUARD_PAGES * page_size);
|
||||
#endif
|
||||
|
||||
stack->pointer = NULL;
|
||||
}
|
||||
|
||||
static ZEND_NORETURN void zend_fiber_trampoline(transfer_t transfer)
|
||||
{
|
||||
zend_fiber_context *context = transfer.data;
|
||||
|
||||
context->caller = transfer.context;
|
||||
|
||||
context->function(context);
|
||||
|
||||
context->self = NULL;
|
||||
|
||||
zend_fiber_suspend_context(context);
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
ZEND_API bool zend_fiber_init_context(zend_fiber_context *context, zend_fiber_coroutine coroutine, size_t stack_size)
|
||||
{
|
||||
if (UNEXPECTED(!zend_fiber_stack_allocate(&context->stack, stack_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stack grows down, calculate the top of the stack. make_fcontext then shifts pointer to lower 16-byte boundary.
|
||||
void *stack = (void *) ((uintptr_t) context->stack.pointer + context->stack.size);
|
||||
|
||||
context->self = make_fcontext(stack, context->stack.size, zend_fiber_trampoline);
|
||||
|
||||
if (UNEXPECTED(!context->self)) {
|
||||
zend_fiber_stack_free(&context->stack);
|
||||
return false;
|
||||
}
|
||||
|
||||
context->function = coroutine;
|
||||
context->caller = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context)
|
||||
{
|
||||
zend_fiber_stack_free(&context->stack);
|
||||
}
|
||||
|
||||
ZEND_API void zend_fiber_switch_context(zend_fiber_context *to)
|
||||
{
|
||||
ZEND_ASSERT(to && to->self && to->stack.pointer && "Invalid fiber context");
|
||||
|
||||
transfer_t transfer = jump_fcontext(to->self, to);
|
||||
|
||||
to->self = transfer.context;
|
||||
}
|
||||
|
||||
ZEND_API void zend_fiber_suspend_context(zend_fiber_context *current)
|
||||
{
|
||||
ZEND_ASSERT(current && current->caller && current->stack.pointer && "Invalid fiber context");
|
||||
|
||||
transfer_t transfer = jump_fcontext(current->caller, NULL);
|
||||
|
||||
current->caller = transfer.context;
|
||||
}
|
||||
|
||||
static void zend_fiber_suspend(zend_fiber *fiber)
|
||||
{
|
||||
zend_vm_stack stack;
|
||||
size_t stack_page_size;
|
||||
zend_execute_data *execute_data;
|
||||
int error_reporting;
|
||||
uint32_t jit_trace_num;
|
||||
|
||||
ZEND_FIBER_BACKUP_EG(stack, stack_page_size, execute_data, error_reporting, jit_trace_num);
|
||||
|
||||
zend_fiber_suspend_context(&fiber->context);
|
||||
|
||||
ZEND_FIBER_RESTORE_EG(stack, stack_page_size, execute_data, error_reporting, jit_trace_num);
|
||||
}
|
||||
|
||||
static void zend_fiber_switch_to(zend_fiber *fiber)
|
||||
{
|
||||
zend_fiber *previous;
|
||||
zend_vm_stack stack;
|
||||
size_t stack_page_size;
|
||||
zend_execute_data *execute_data;
|
||||
int error_reporting;
|
||||
uint32_t jit_trace_num;
|
||||
|
||||
previous = EG(current_fiber);
|
||||
|
||||
zend_observer_fiber_switch_notify(previous, fiber);
|
||||
|
||||
ZEND_FIBER_BACKUP_EG(stack, stack_page_size, execute_data, error_reporting, jit_trace_num);
|
||||
|
||||
EG(current_fiber) = fiber;
|
||||
|
||||
zend_fiber_switch_context(&fiber->context);
|
||||
|
||||
EG(current_fiber) = previous;
|
||||
|
||||
ZEND_FIBER_RESTORE_EG(stack, stack_page_size, execute_data, error_reporting, jit_trace_num);
|
||||
|
||||
zend_observer_fiber_switch_notify(fiber, previous);
|
||||
|
||||
if (UNEXPECTED(EG(fiber_error)) && fiber->status != ZEND_FIBER_STATUS_SHUTDOWN) {
|
||||
if (previous) {
|
||||
zend_fiber_suspend(previous); // Still in fiber, suspend again until in {main}.
|
||||
abort(); // This fiber should never be resumed.
|
||||
}
|
||||
|
||||
zend_fiber_error *error = EG(fiber_error);
|
||||
zend_error_zstr_at(error->type, error->filename, error->lineno, error->message);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_COLD void zend_error_suspend_fiber(
|
||||
int orig_type, zend_string *error_filename, uint32_t error_lineno, zend_string *message)
|
||||
{
|
||||
ZEND_ASSERT(EG(current_fiber) && "Must be within an active fiber!");
|
||||
|
||||
zend_fiber_error *error = emalloc(sizeof(zend_fiber_error));
|
||||
|
||||
error->type = orig_type;
|
||||
error->filename = error_filename;
|
||||
error->lineno = error_lineno;
|
||||
error->message = message;
|
||||
|
||||
EG(fiber_error) = error;
|
||||
|
||||
zend_fiber_suspend(EG(current_fiber));
|
||||
|
||||
abort(); // This fiber should never be resumed.
|
||||
}
|
||||
|
||||
static zend_always_inline zend_vm_stack zend_fiber_vm_stack_alloc(size_t size)
|
||||
{
|
||||
zend_vm_stack page = emalloc(size);
|
||||
|
||||
page->top = ZEND_VM_STACK_ELEMENTS(page);
|
||||
page->end = (zval *) ((uintptr_t) page + size);
|
||||
page->prev = NULL;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
static void ZEND_STACK_ALIGNED zend_fiber_execute(zend_fiber_context *context)
|
||||
{
|
||||
zend_fiber *fiber = EG(current_fiber);
|
||||
ZEND_ASSERT(fiber);
|
||||
|
||||
zend_long error_reporting = INI_INT("error_reporting");
|
||||
if (!error_reporting && !INI_STR("error_reporting")) {
|
||||
error_reporting = E_ALL;
|
||||
}
|
||||
|
||||
zend_vm_stack stack = zend_fiber_vm_stack_alloc(ZEND_FIBER_VM_STACK_SIZE);
|
||||
EG(vm_stack) = stack;
|
||||
EG(vm_stack_top) = stack->top + ZEND_CALL_FRAME_SLOT;
|
||||
EG(vm_stack_end) = stack->end;
|
||||
EG(vm_stack_page_size) = ZEND_FIBER_VM_STACK_SIZE;
|
||||
|
||||
fiber->execute_data = (zend_execute_data *) stack->top;
|
||||
|
||||
memset(fiber->execute_data, 0, sizeof(zend_execute_data));
|
||||
|
||||
EG(current_execute_data) = fiber->execute_data;
|
||||
EG(jit_trace_num) = 0;
|
||||
EG(error_reporting) = error_reporting;
|
||||
|
||||
fiber->fci.retval = &fiber->value;
|
||||
|
||||
fiber->status = ZEND_FIBER_STATUS_RUNNING;
|
||||
|
||||
zend_call_function(&fiber->fci, &fiber->fci_cache);
|
||||
|
||||
zval_ptr_dtor(&fiber->fci.function_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
if (fiber->status == ZEND_FIBER_STATUS_SHUTDOWN) {
|
||||
if (EXPECTED(zend_is_graceful_exit(EG(exception)) || zend_is_unwind_exit(EG(exception)))) {
|
||||
zend_clear_exception();
|
||||
} else {
|
||||
zend_exception_error(EG(exception), E_ERROR);
|
||||
}
|
||||
} else {
|
||||
fiber->status = ZEND_FIBER_STATUS_THREW;
|
||||
}
|
||||
} else {
|
||||
fiber->status = ZEND_FIBER_STATUS_RETURNED;
|
||||
}
|
||||
|
||||
zend_vm_stack_destroy();
|
||||
fiber->execute_data = NULL;
|
||||
}
|
||||
|
||||
static zend_object *zend_fiber_object_create(zend_class_entry *ce)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
fiber = emalloc(sizeof(zend_fiber));
|
||||
memset(fiber, 0, sizeof(zend_fiber));
|
||||
|
||||
zend_object_std_init(&fiber->std, ce);
|
||||
fiber->std.handlers = &zend_fiber_handlers;
|
||||
|
||||
return &fiber->std;
|
||||
}
|
||||
|
||||
static void zend_fiber_object_destroy(zend_object *object)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) object;
|
||||
|
||||
if (fiber->status == ZEND_FIBER_STATUS_SUSPENDED) {
|
||||
zend_object *exception = EG(exception);
|
||||
EG(exception) = NULL;
|
||||
|
||||
fiber->status = ZEND_FIBER_STATUS_SHUTDOWN;
|
||||
|
||||
zend_fiber_switch_to(fiber);
|
||||
|
||||
EG(exception) = exception;
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_fiber_object_free(zend_object *object)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) object;
|
||||
|
||||
if (fiber->status == ZEND_FIBER_STATUS_INIT) {
|
||||
// Fiber was never started, so we need to release the reference to the callback.
|
||||
zval_ptr_dtor(&fiber->fci.function_name);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&fiber->value);
|
||||
|
||||
zend_fiber_destroy_context(&fiber->context);
|
||||
|
||||
zend_object_std_dtor(&fiber->std);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, __construct)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_FUNC(fiber->fci, fiber->fci_cache)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
// Keep a reference to closures or callable objects while the fiber is running.
|
||||
Z_TRY_ADDREF(fiber->fci.function_name);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, start)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
zval *params;
|
||||
uint32_t param_count;
|
||||
zend_array *named_params;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, -1)
|
||||
Z_PARAM_VARIADIC_WITH_NAMED(params, param_count, named_params);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (fiber->status != ZEND_FIBER_STATUS_INIT) {
|
||||
zend_throw_error(zend_ce_fiber_error, "Cannot start a fiber that has already been started");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
fiber->fci.params = params;
|
||||
fiber->fci.param_count = param_count;
|
||||
fiber->fci.named_params = named_params;
|
||||
|
||||
if (!zend_fiber_init_context(&fiber->context, zend_fiber_execute, EG(fiber_stack_size))) {
|
||||
zend_throw_exception(NULL, "Could not create fiber context", 0);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
zend_fiber_switch_to(fiber);
|
||||
|
||||
if (fiber->status & ZEND_FIBER_STATUS_FINISHED) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
RETVAL_COPY_VALUE(&fiber->value);
|
||||
ZVAL_UNDEF(&fiber->value);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, suspend)
|
||||
{
|
||||
zend_fiber *fiber = EG(current_fiber);
|
||||
zval *exception, *value = NULL;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_ZVAL(value);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (UNEXPECTED(!fiber)) {
|
||||
zend_throw_error(zend_ce_fiber_error, "Cannot suspend outside of a fiber");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (UNEXPECTED(fiber->status == ZEND_FIBER_STATUS_SHUTDOWN)) {
|
||||
zend_throw_error(zend_ce_fiber_error, "Cannot suspend in a force closed fiber");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
ZEND_ASSERT(fiber->status == ZEND_FIBER_STATUS_RUNNING);
|
||||
|
||||
if (value) {
|
||||
ZVAL_COPY(&fiber->value, value);
|
||||
} else {
|
||||
ZVAL_NULL(&fiber->value);
|
||||
}
|
||||
|
||||
fiber->execute_data = execute_data;
|
||||
fiber->status = ZEND_FIBER_STATUS_SUSPENDED;
|
||||
|
||||
zend_fiber_suspend(fiber);
|
||||
|
||||
if (fiber->status == ZEND_FIBER_STATUS_SHUTDOWN) {
|
||||
// This occurs when the fiber is GC'ed while suspended.
|
||||
if (EG(fiber_error)) {
|
||||
// Throw UnwindExit so finally blocks are not executed on fatal error.
|
||||
zend_throw_unwind_exit();
|
||||
} else {
|
||||
// Otherwise throw GracefulExit to execute finally blocks.
|
||||
zend_throw_graceful_exit();
|
||||
}
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
fiber->status = ZEND_FIBER_STATUS_RUNNING;
|
||||
|
||||
if (fiber->exception) {
|
||||
exception = fiber->exception;
|
||||
fiber->exception = NULL;
|
||||
|
||||
zend_throw_exception_object(exception);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
RETVAL_COPY_VALUE(&fiber->value);
|
||||
ZVAL_UNDEF(&fiber->value);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, resume)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
zval *value = NULL;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_ZVAL(value);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
if (UNEXPECTED(fiber->status != ZEND_FIBER_STATUS_SUSPENDED)) {
|
||||
zend_throw_error(zend_ce_fiber_error, "Cannot resume a fiber that is not suspended");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (value) {
|
||||
ZVAL_COPY(&fiber->value, value);
|
||||
} else {
|
||||
ZVAL_NULL(&fiber->value);
|
||||
}
|
||||
|
||||
fiber->status = ZEND_FIBER_STATUS_RUNNING;
|
||||
|
||||
zend_fiber_switch_to(fiber);
|
||||
|
||||
if (fiber->status & ZEND_FIBER_STATUS_FINISHED) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
RETVAL_COPY_VALUE(&fiber->value);
|
||||
ZVAL_UNDEF(&fiber->value);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, throw)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
zval *exception;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_OF_CLASS(exception, zend_ce_throwable)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
if (UNEXPECTED(fiber->status != ZEND_FIBER_STATUS_SUSPENDED)) {
|
||||
zend_throw_error(zend_ce_fiber_error, "Cannot resume a fiber that is not suspended");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
Z_ADDREF_P(exception);
|
||||
fiber->exception = exception;
|
||||
|
||||
fiber->status = ZEND_FIBER_STATUS_RUNNING;
|
||||
|
||||
zend_fiber_switch_to(fiber);
|
||||
|
||||
if (fiber->status & ZEND_FIBER_STATUS_FINISHED) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
RETVAL_COPY_VALUE(&fiber->value);
|
||||
ZVAL_UNDEF(&fiber->value);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, isStarted)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
RETURN_BOOL(fiber->status != ZEND_FIBER_STATUS_INIT);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, isSuspended)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
RETURN_BOOL(fiber->status == ZEND_FIBER_STATUS_SUSPENDED);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, isRunning)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
RETURN_BOOL(fiber->status == ZEND_FIBER_STATUS_RUNNING);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, isTerminated)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
RETURN_BOOL(fiber->status & ZEND_FIBER_STATUS_FINISHED);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, getReturn)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
fiber = (zend_fiber *) Z_OBJ_P(getThis());
|
||||
|
||||
if (fiber->status != ZEND_FIBER_STATUS_RETURNED) {
|
||||
const char *message;
|
||||
|
||||
if (fiber->status == ZEND_FIBER_STATUS_INIT) {
|
||||
message = "The fiber has not been started";
|
||||
} else if (fiber->status == ZEND_FIBER_STATUS_THREW) {
|
||||
message = "The fiber threw an exception";
|
||||
} else {
|
||||
message = "The fiber has not returned";
|
||||
}
|
||||
|
||||
zend_throw_error(zend_ce_fiber_error, "Cannot get fiber return value: %s", message);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
RETURN_COPY(&fiber->value);
|
||||
}
|
||||
|
||||
ZEND_METHOD(Fiber, this)
|
||||
{
|
||||
zend_fiber *fiber;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
fiber = EG(current_fiber);
|
||||
|
||||
if (!fiber) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
RETURN_OBJ_COPY(&fiber->std);
|
||||
}
|
||||
|
||||
ZEND_METHOD(FiberError, __construct)
|
||||
{
|
||||
zend_throw_error(
|
||||
NULL,
|
||||
"The \"%s\" class is reserved for internal use and cannot be manually instantiated",
|
||||
ZSTR_VAL(Z_OBJCE_P(getThis())->name)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void zend_register_fiber_ce(void)
|
||||
{
|
||||
zend_ce_fiber = register_class_Fiber();
|
||||
zend_ce_fiber->create_object = zend_fiber_object_create;
|
||||
zend_ce_fiber->serialize = zend_class_serialize_deny;
|
||||
zend_ce_fiber->unserialize = zend_class_unserialize_deny;
|
||||
|
||||
zend_fiber_handlers = std_object_handlers;
|
||||
zend_fiber_handlers.dtor_obj = zend_fiber_object_destroy;
|
||||
zend_fiber_handlers.free_obj = zend_fiber_object_free;
|
||||
zend_fiber_handlers.clone_obj = NULL;
|
||||
|
||||
zend_ce_fiber_error = register_class_FiberError(zend_ce_error);
|
||||
zend_ce_fiber_error->create_object = zend_ce_error->create_object;
|
||||
}
|
||||
|
||||
void zend_fiber_init(void)
|
||||
{
|
||||
EG(current_fiber) = NULL;
|
||||
EG(fiber_error) = NULL;
|
||||
}
|
110
Zend/zend_fibers.h
Normal file
110
Zend/zend_fibers.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Aaron Piotrowski <aaron@trowski.com> |
|
||||
| Martin Schröder <m.schroeder2007@gmail.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef ZEND_FIBERS_H
|
||||
#define ZEND_FIBERS_H
|
||||
|
||||
#include "zend_API.h"
|
||||
#include "zend_types.h"
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
void zend_register_fiber_ce(void);
|
||||
void zend_fiber_init(void);
|
||||
|
||||
extern ZEND_API zend_class_entry *zend_ce_fiber;
|
||||
|
||||
typedef struct _zend_fiber_context zend_fiber_context;
|
||||
|
||||
typedef void (*zend_fiber_coroutine)(zend_fiber_context *context);
|
||||
|
||||
typedef struct _zend_fiber_stack {
|
||||
void *pointer;
|
||||
size_t size;
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
int valgrind;
|
||||
#endif
|
||||
} zend_fiber_stack;
|
||||
|
||||
typedef struct _zend_fiber_context {
|
||||
void *self;
|
||||
void *caller;
|
||||
zend_fiber_coroutine function;
|
||||
zend_fiber_stack stack;
|
||||
} zend_fiber_context;
|
||||
|
||||
typedef struct _zend_fiber {
|
||||
/* Fiber PHP object handle. */
|
||||
zend_object std;
|
||||
|
||||
/* Status of the fiber, one of the ZEND_FIBER_STATUS_* constants. */
|
||||
zend_uchar status;
|
||||
|
||||
/* Callback and info / cache to be used when fiber is started. */
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fci_cache;
|
||||
|
||||
/* Context of this fiber, will be initialized during call to Fiber::start(). */
|
||||
zend_fiber_context context;
|
||||
|
||||
/* Current Zend VM execute data being run by the fiber. */
|
||||
zend_execute_data *execute_data;
|
||||
|
||||
/* Exception to be thrown from Fiber::suspend(). */
|
||||
zval *exception;
|
||||
|
||||
/* Storage for temporaries and fiber return value. */
|
||||
zval value;
|
||||
} zend_fiber;
|
||||
|
||||
typedef struct _zend_fiber_error {
|
||||
int type;
|
||||
zend_string *filename;
|
||||
uint32_t lineno;
|
||||
zend_string *message;
|
||||
} zend_fiber_error;
|
||||
|
||||
static const zend_uchar ZEND_FIBER_STATUS_INIT = 0x0;
|
||||
static const zend_uchar ZEND_FIBER_STATUS_SUSPENDED = 0x1;
|
||||
static const zend_uchar ZEND_FIBER_STATUS_RUNNING = 0x2;
|
||||
static const zend_uchar ZEND_FIBER_STATUS_RETURNED = 0x4;
|
||||
static const zend_uchar ZEND_FIBER_STATUS_THREW = 0x8;
|
||||
static const zend_uchar ZEND_FIBER_STATUS_SHUTDOWN = 0x10;
|
||||
|
||||
static const zend_uchar ZEND_FIBER_STATUS_FINISHED = 0x1c;
|
||||
|
||||
ZEND_API zend_bool zend_fiber_init_context(zend_fiber_context *context, zend_fiber_coroutine coroutine, size_t stack_size);
|
||||
ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context);
|
||||
|
||||
ZEND_COLD void zend_error_suspend_fiber(
|
||||
int orig_type, zend_string *error_filename, uint32_t error_lineno, zend_string *message);
|
||||
|
||||
ZEND_API void zend_fiber_switch_context(zend_fiber_context *to);
|
||||
ZEND_API void zend_fiber_suspend_context(zend_fiber_context *current);
|
||||
|
||||
#define ZEND_FIBER_GUARD_PAGES 1
|
||||
|
||||
#define ZEND_FIBER_DEFAULT_C_STACK_SIZE (4096 * (((sizeof(void *)) < 8) ? 256 : 512))
|
||||
|
||||
#define ZEND_FIBER_VM_STACK_SIZE (1024 * sizeof(zval))
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
34
Zend/zend_fibers.stub.php
Normal file
34
Zend/zend_fibers.stub.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/** @generate-class-entries */
|
||||
|
||||
/** @strict-properties */
|
||||
final class Fiber
|
||||
{
|
||||
public function __construct(callable $callback) {}
|
||||
|
||||
public function start(mixed ...$args): mixed {}
|
||||
|
||||
public function resume(mixed $value = null): mixed {}
|
||||
|
||||
public function throw(Throwable $exception): mixed {}
|
||||
|
||||
public function isStarted(): bool {}
|
||||
|
||||
public function isSuspended(): bool {}
|
||||
|
||||
public function isRunning(): bool {}
|
||||
|
||||
public function isTerminated(): bool {}
|
||||
|
||||
public function getReturn(): mixed {}
|
||||
|
||||
public static function this(): ?Fiber {}
|
||||
|
||||
public static function suspend(mixed $value = null): mixed {}
|
||||
}
|
||||
|
||||
final class FiberError extends Error
|
||||
{
|
||||
public function __construct() {}
|
||||
}
|
96
Zend/zend_fibers_arginfo.h
Normal file
96
Zend/zend_fibers_arginfo.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 5f63019ce24efa7b5426f172d68a0f9f705a3bd5 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Fiber___construct, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Fiber_start, 0, 0, IS_MIXED, 0)
|
||||
ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Fiber_resume, 0, 0, IS_MIXED, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_MIXED, 0, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Fiber_throw, 0, 1, IS_MIXED, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, exception, Throwable, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Fiber_isStarted, 0, 0, _IS_BOOL, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_Fiber_isSuspended arginfo_class_Fiber_isStarted
|
||||
|
||||
#define arginfo_class_Fiber_isRunning arginfo_class_Fiber_isStarted
|
||||
|
||||
#define arginfo_class_Fiber_isTerminated arginfo_class_Fiber_isStarted
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Fiber_getReturn, 0, 0, IS_MIXED, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Fiber_this, 0, 0, Fiber, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_Fiber_suspend arginfo_class_Fiber_resume
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_FiberError___construct, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_METHOD(Fiber, __construct);
|
||||
ZEND_METHOD(Fiber, start);
|
||||
ZEND_METHOD(Fiber, resume);
|
||||
ZEND_METHOD(Fiber, throw);
|
||||
ZEND_METHOD(Fiber, isStarted);
|
||||
ZEND_METHOD(Fiber, isSuspended);
|
||||
ZEND_METHOD(Fiber, isRunning);
|
||||
ZEND_METHOD(Fiber, isTerminated);
|
||||
ZEND_METHOD(Fiber, getReturn);
|
||||
ZEND_METHOD(Fiber, this);
|
||||
ZEND_METHOD(Fiber, suspend);
|
||||
ZEND_METHOD(FiberError, __construct);
|
||||
|
||||
|
||||
static const zend_function_entry class_Fiber_methods[] = {
|
||||
ZEND_ME(Fiber, __construct, arginfo_class_Fiber___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, start, arginfo_class_Fiber_start, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, resume, arginfo_class_Fiber_resume, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, throw, arginfo_class_Fiber_throw, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, isStarted, arginfo_class_Fiber_isStarted, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, isSuspended, arginfo_class_Fiber_isSuspended, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, isRunning, arginfo_class_Fiber_isRunning, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, isTerminated, arginfo_class_Fiber_isTerminated, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, getReturn, arginfo_class_Fiber_getReturn, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(Fiber, this, arginfo_class_Fiber_this, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_ME(Fiber, suspend, arginfo_class_Fiber_suspend, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
||||
static const zend_function_entry class_FiberError_methods[] = {
|
||||
ZEND_ME(FiberError, __construct, arginfo_class_FiberError___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_Fiber(void)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "Fiber", class_Fiber_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, NULL);
|
||||
class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES;
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
static zend_class_entry *register_class_FiberError(zend_class_entry *class_entry_Error)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "FiberError", class_FiberError_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error);
|
||||
class_entry->ce_flags |= ZEND_ACC_FINAL;
|
||||
|
||||
return class_entry;
|
||||
}
|
|
@ -61,6 +61,8 @@ END_EXTERN_C()
|
|||
|
||||
typedef struct _zend_vm_stack *zend_vm_stack;
|
||||
typedef struct _zend_ini_entry zend_ini_entry;
|
||||
typedef struct _zend_fiber zend_fiber;
|
||||
typedef struct _zend_fiber_error zend_fiber_error;
|
||||
|
||||
|
||||
struct _zend_compiler_globals {
|
||||
|
@ -249,6 +251,15 @@ struct _zend_executor_globals {
|
|||
|
||||
zend_get_gc_buffer get_gc_buffer;
|
||||
|
||||
/* Active fiber, NULL when in main thread. */
|
||||
zend_fiber *current_fiber;
|
||||
|
||||
/* Default fiber C stack size. */
|
||||
zend_long fiber_stack_size;
|
||||
|
||||
/* Pointer to fatal error that occurred in a fiber while switching to {main}. */
|
||||
zend_fiber_error *fiber_error;
|
||||
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct _zend_observer_fcall_data {
|
|||
|
||||
zend_llist zend_observers_fcall_list;
|
||||
zend_llist zend_observer_error_callbacks;
|
||||
zend_llist zend_observer_fiber_switch;
|
||||
|
||||
int zend_observer_fcall_op_array_extension = -1;
|
||||
|
||||
|
@ -72,6 +73,7 @@ ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) {
|
|||
ZEND_API void zend_observer_startup(void) {
|
||||
zend_llist_init(&zend_observers_fcall_list, sizeof(zend_observer_fcall_init), NULL, 1);
|
||||
zend_llist_init(&zend_observer_error_callbacks, sizeof(zend_observer_error_cb), NULL, 1);
|
||||
zend_llist_init(&zend_observer_fiber_switch, sizeof(zend_observer_fiber_switch_handler), NULL, 1);
|
||||
}
|
||||
|
||||
ZEND_API void zend_observer_activate(void) {
|
||||
|
@ -89,6 +91,7 @@ ZEND_API void zend_observer_deactivate(void) {
|
|||
ZEND_API void zend_observer_shutdown(void) {
|
||||
zend_llist_destroy(&zend_observers_fcall_list);
|
||||
zend_llist_destroy(&zend_observer_error_callbacks);
|
||||
zend_llist_destroy(&zend_observer_fiber_switch);
|
||||
}
|
||||
|
||||
static void zend_observer_fcall_install(zend_execute_data *execute_data) {
|
||||
|
@ -255,3 +258,19 @@ void zend_observer_error_notify(int type, zend_string *error_filename, uint32_t
|
|||
callback(type, error_filename, error_lineno, message);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_observer_fiber_switch_register(zend_observer_fiber_switch_handler handler)
|
||||
{
|
||||
zend_llist_add_element(&zend_observer_fiber_switch, &handler);
|
||||
}
|
||||
|
||||
void zend_observer_fiber_switch_notify(zend_fiber *from, zend_fiber *to)
|
||||
{
|
||||
zend_llist_element *element;
|
||||
zend_observer_fiber_switch_handler callback;
|
||||
|
||||
for (element = zend_observer_fiber_switch.head; element; element = element->next) {
|
||||
callback = *(zend_observer_fiber_switch_handler *) element->data;
|
||||
callback(from, to);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "zend.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_fibers.h"
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
|
@ -77,6 +78,11 @@ typedef void (*zend_observer_error_cb)(int type, zend_string *error_filename, ui
|
|||
ZEND_API void zend_observer_error_register(zend_observer_error_cb callback);
|
||||
void zend_observer_error_notify(int type, zend_string *error_filename, uint32_t error_lineno, zend_string *message);
|
||||
|
||||
typedef void (*zend_observer_fiber_switch_handler)(zend_fiber *from, zend_fiber *to);
|
||||
|
||||
ZEND_API void zend_observer_fiber_switch_register(zend_observer_fiber_switch_handler handler);
|
||||
void zend_observer_fiber_switch_notify(zend_fiber *from, zend_fiber *to);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif /* ZEND_OBSERVER_H */
|
||||
|
|
|
@ -281,6 +281,12 @@ char *alloca();
|
|||
# define ZEND_NORETURN
|
||||
#endif
|
||||
|
||||
#if __has_attribute(force_align_arg_pointer)
|
||||
# define ZEND_STACK_ALIGNED __attribute__((force_align_arg_pointer))
|
||||
#else
|
||||
# define ZEND_STACK_ALIGNED
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__))
|
||||
# define HAVE_NORETURN_ALIAS
|
||||
# define HAVE_ATTRIBUTE_WEAK
|
||||
|
|
51
configure.ac
51
configure.ac
|
@ -1181,6 +1181,55 @@ dnl ----------------------------------------------------------------------------
|
|||
PHP_HELP_SEPARATOR([Zend:])
|
||||
PHP_CONFIGURE_PART(Configuring Zend)
|
||||
|
||||
AC_MSG_CHECKING(for fiber switching context)
|
||||
fibers="yes"
|
||||
|
||||
AS_CASE([$host_cpu],
|
||||
[x86_64*|amd64*], [fiber_cpu="x86_64"],
|
||||
[x86*|amd*|i?86*|pentium], [fiber_cpu="i386"],
|
||||
[aarch64*|arm64*], [fiber_cpu="arm64"],
|
||||
[arm*], [fiber_cpu="arm32"],
|
||||
[ppc64*], [fiber_cpu="ppc64"],
|
||||
[powerpc*], [fiber_cpu="ppc32"],
|
||||
[s390x*], [fiber_cpu="s390x"],
|
||||
[mips64*], [fiber_cpu="mips64"],
|
||||
[mips*], [fiber_cpu="mips32"],
|
||||
[fiber_cpu="unknown"]
|
||||
)
|
||||
|
||||
AS_CASE([$host_os],
|
||||
[darwin*], [fiber_os="mac"],
|
||||
[fiber_os="other"]
|
||||
)
|
||||
|
||||
AS_CASE([$fiber_cpu],
|
||||
[x86_64], [fiber_asm_file_prefix="x86_64_sysv"],
|
||||
[i386], [fiber_asm_file_prefix="i386_sysv"],
|
||||
[arm64], [fiber_asm_file_prefix="arm64_aapcs"],
|
||||
[arm32], [fiber_asm_file_prefix="arm_aapcs"],
|
||||
[ppc64], [fiber_asm_file_prefix="ppc64_sysv"],
|
||||
[ppc32], [fiber_asm_file_prefix="ppc_sysv"],
|
||||
[s390x], [fiber_asm_file_prefix="s390x_sysv"],
|
||||
[mips64], [fiber_asm_file_prefix="mips64_n64"],
|
||||
[mips32], [fiber_asm_file_prefix="mips32_o32"],
|
||||
[fiber_asm_file_prefix="unknown"]
|
||||
)
|
||||
|
||||
if test "$fiber_os" = 'mac'; then
|
||||
fiber_asm_file="combined_sysv_macho_gas.S"
|
||||
elif test "$fiber_asm_file_prefix" != 'unknown'; then
|
||||
fiber_asm_file="${fiber_asm_file_prefix}_elf_gas.S"
|
||||
else
|
||||
fibers="no"
|
||||
fi
|
||||
|
||||
if test "$fibers" = 'yes'; then
|
||||
PHP_ADD_SOURCES(Zend/asm, make_${fiber_asm_file} jump_${fiber_asm_file})
|
||||
AC_MSG_RESULT([$fiber_asm_file])
|
||||
else
|
||||
AC_MSG_ERROR([Unable to determine platform!])
|
||||
fi
|
||||
|
||||
LIBZEND_BASIC_CHECKS
|
||||
LIBZEND_DLSYM_CHECK
|
||||
LIBZEND_OTHER_CHECKS
|
||||
|
@ -1544,7 +1593,7 @@ PHP_ADD_SOURCES(Zend, \
|
|||
zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \
|
||||
zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \
|
||||
zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \
|
||||
zend_observer.c zend_system_id.c zend_enum.c \
|
||||
zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c \
|
||||
Optimizer/zend_optimizer.c \
|
||||
Optimizer/pass1.c \
|
||||
Optimizer/pass3.c \
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "zend_builtin_functions.h"
|
||||
#include "zend_smart_str.h"
|
||||
#include "zend_enum.h"
|
||||
#include "zend_fibers.h"
|
||||
#include "php_reflection_arginfo.h"
|
||||
|
||||
/* Key used to avoid leaking addresses in ReflectionProperty::getId() */
|
||||
|
@ -91,6 +92,7 @@ PHPAPI zend_class_entry *reflection_attribute_ptr;
|
|||
PHPAPI zend_class_entry *reflection_enum_ptr;
|
||||
PHPAPI zend_class_entry *reflection_enum_unit_case_ptr;
|
||||
PHPAPI zend_class_entry *reflection_enum_backed_case_ptr;
|
||||
PHPAPI zend_class_entry *reflection_fiber_ptr;
|
||||
|
||||
/* Exception throwing macro */
|
||||
#define _DO_THROW(msg) \
|
||||
|
@ -154,6 +156,7 @@ typedef enum {
|
|||
REF_TYPE_OTHER, /* Must be 0 */
|
||||
REF_TYPE_FUNCTION,
|
||||
REF_TYPE_GENERATOR,
|
||||
REF_TYPE_FIBER,
|
||||
REF_TYPE_PARAMETER,
|
||||
REF_TYPE_TYPE,
|
||||
REF_TYPE_PROPERTY,
|
||||
|
@ -266,6 +269,7 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */
|
|||
break;
|
||||
}
|
||||
case REF_TYPE_GENERATOR:
|
||||
case REF_TYPE_FIBER:
|
||||
case REF_TYPE_CLASS_CONSTANT:
|
||||
case REF_TYPE_OTHER:
|
||||
break;
|
||||
|
@ -6745,6 +6749,115 @@ ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue)
|
|||
ZVAL_COPY_OR_DUP(return_value, member_p);
|
||||
}
|
||||
|
||||
/* {{{ proto ReflectionFiber::__construct(Fiber $fiber) */
|
||||
ZEND_METHOD(ReflectionFiber, __construct)
|
||||
{
|
||||
zval *fiber, *object;
|
||||
reflection_object *intern;
|
||||
|
||||
object = ZEND_THIS;
|
||||
intern = Z_REFLECTION_P(object);
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_OF_CLASS(fiber, zend_ce_fiber)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (intern->ce) {
|
||||
zval_ptr_dtor(&intern->obj);
|
||||
}
|
||||
|
||||
intern->ref_type = REF_TYPE_FIBER;
|
||||
ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(fiber));
|
||||
intern->ce = zend_ce_fiber;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_METHOD(ReflectionFiber, getFiber)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
RETURN_OBJ_COPY(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj));
|
||||
}
|
||||
|
||||
#define REFLECTION_CHECK_VALID_FIBER(fiber) do { \
|
||||
if (fiber == NULL || fiber->status == ZEND_FIBER_STATUS_INIT || fiber->status & ZEND_FIBER_STATUS_FINISHED) { \
|
||||
zend_throw_error(NULL, "Cannot fetch information from a fiber that has not been started or is terminated"); \
|
||||
RETURN_THROWS(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
ZEND_METHOD(ReflectionFiber, getTrace)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj);
|
||||
zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG(options);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
REFLECTION_CHECK_VALID_FIBER(fiber);
|
||||
|
||||
if (EG(current_fiber) != fiber) {
|
||||
// No need to replace current execute data if within the current fiber.
|
||||
EG(current_execute_data) = fiber->execute_data;
|
||||
}
|
||||
|
||||
zend_fetch_debug_backtrace(return_value, 0, options, 0);
|
||||
|
||||
EG(current_execute_data) = execute_data; // Restore original execute data.
|
||||
}
|
||||
|
||||
ZEND_METHOD(ReflectionFiber, getExecutingLine)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj);
|
||||
zend_execute_data *prev_execute_data;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
REFLECTION_CHECK_VALID_FIBER(fiber);
|
||||
|
||||
if (EG(current_fiber) == fiber) {
|
||||
prev_execute_data = execute_data->prev_execute_data;
|
||||
} else {
|
||||
prev_execute_data = fiber->execute_data->prev_execute_data;
|
||||
}
|
||||
|
||||
RETURN_LONG(prev_execute_data->opline->lineno);
|
||||
}
|
||||
|
||||
ZEND_METHOD(ReflectionFiber, getExecutingFile)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj);
|
||||
zend_execute_data *prev_execute_data;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
REFLECTION_CHECK_VALID_FIBER(fiber);
|
||||
|
||||
if (EG(current_fiber) == fiber) {
|
||||
prev_execute_data = execute_data->prev_execute_data;
|
||||
} else {
|
||||
prev_execute_data = fiber->execute_data->prev_execute_data;
|
||||
}
|
||||
|
||||
RETURN_STR_COPY(prev_execute_data->func->op_array.filename);
|
||||
}
|
||||
|
||||
ZEND_METHOD(ReflectionFiber, getCallable)
|
||||
{
|
||||
zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj);
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
if (fiber == NULL || fiber->status & ZEND_FIBER_STATUS_FINISHED) {
|
||||
zend_throw_error(NULL, "Cannot fetch the callable from a fiber that has terminated"); \
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
RETURN_COPY(&fiber->fci.function_name);
|
||||
}
|
||||
|
||||
/* {{{ _reflection_write_property */
|
||||
static zval *_reflection_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
|
||||
{
|
||||
|
@ -6863,6 +6976,9 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
|
|||
reflection_enum_backed_case_ptr = register_class_ReflectionEnumBackedCase(reflection_enum_unit_case_ptr);
|
||||
reflection_init_class_handlers(reflection_enum_backed_case_ptr);
|
||||
|
||||
reflection_fiber_ptr = register_class_ReflectionFiber();
|
||||
reflection_init_class_handlers(reflection_fiber_ptr);
|
||||
|
||||
REGISTER_REFLECTION_CLASS_CONST_LONG(attribute, "IS_INSTANCEOF", REFLECTION_ATTRIBUTE_IS_INSTANCEOF);
|
||||
|
||||
REFLECTION_G(key_initialized) = 0;
|
||||
|
|
|
@ -46,6 +46,7 @@ extern PHPAPI zend_class_entry *reflection_attribute_ptr;
|
|||
extern PHPAPI zend_class_entry *reflection_enum_ptr;
|
||||
extern PHPAPI zend_class_entry *reflection_enum_unit_case_ptr;
|
||||
extern PHPAPI zend_class_entry *reflection_enum_backed_case_ptr;
|
||||
extern PHPAPI zend_class_entry *reflection_fiber_ptr;
|
||||
|
||||
PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object);
|
||||
|
||||
|
|
|
@ -720,3 +720,18 @@ final class ReflectionEnumBackedCase extends ReflectionEnumUnitCase
|
|||
|
||||
public function getBackingValue(): int|string {}
|
||||
}
|
||||
|
||||
final class ReflectionFiber
|
||||
{
|
||||
public function __construct(Fiber $fiber) {}
|
||||
|
||||
public function getFiber(): Fiber {}
|
||||
|
||||
public function getExecutingFile(): string {}
|
||||
|
||||
public function getExecutingLine(): int {}
|
||||
|
||||
public function getCallable(): callable {}
|
||||
|
||||
public function getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT): array {}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 6f36123e16ed34e45a527094ab643b6b57669a5d */
|
||||
* Stub hash: 388312e928b54992da6b7e0e0f15dec72d9290f1 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
|
||||
|
@ -523,6 +523,24 @@ ZEND_END_ARG_INFO()
|
|||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionEnumBackedCase_getBackingValue, 0, 0, MAY_BE_LONG|MAY_BE_STRING)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionFiber___construct, 0, 0, 1)
|
||||
ZEND_ARG_OBJ_INFO(0, fiber, Fiber, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionFiber_getFiber, 0, 0, Fiber, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionFiber_getExecutingFile arginfo_class_ReflectionFunction___toString
|
||||
|
||||
#define arginfo_class_ReflectionFiber_getExecutingLine arginfo_class_ReflectionAttribute_getTarget
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionFiber_getCallable, 0, 0, IS_CALLABLE, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionFiber_getTrace, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "DEBUG_BACKTRACE_PROVIDE_OBJECT")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_METHOD(Reflection, getModifierNames);
|
||||
ZEND_METHOD(ReflectionClass, __clone);
|
||||
|
@ -736,6 +754,12 @@ ZEND_METHOD(ReflectionEnumUnitCase, __construct);
|
|||
ZEND_METHOD(ReflectionEnumUnitCase, getEnum);
|
||||
ZEND_METHOD(ReflectionEnumBackedCase, __construct);
|
||||
ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue);
|
||||
ZEND_METHOD(ReflectionFiber, __construct);
|
||||
ZEND_METHOD(ReflectionFiber, getFiber);
|
||||
ZEND_METHOD(ReflectionFiber, getExecutingFile);
|
||||
ZEND_METHOD(ReflectionFiber, getExecutingLine);
|
||||
ZEND_METHOD(ReflectionFiber, getCallable);
|
||||
ZEND_METHOD(ReflectionFiber, getTrace);
|
||||
|
||||
|
||||
static const zend_function_entry class_ReflectionException_methods[] = {
|
||||
|
@ -1069,6 +1093,17 @@ static const zend_function_entry class_ReflectionEnumBackedCase_methods[] = {
|
|||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
||||
static const zend_function_entry class_ReflectionFiber_methods[] = {
|
||||
ZEND_ME(ReflectionFiber, __construct, arginfo_class_ReflectionFiber___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFiber, getFiber, arginfo_class_ReflectionFiber_getFiber, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFiber, getExecutingFile, arginfo_class_ReflectionFiber_getExecutingFile, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFiber, getExecutingLine, arginfo_class_ReflectionFiber_getExecutingLine, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFiber, getCallable, arginfo_class_ReflectionFiber_getCallable, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFiber, getTrace, arginfo_class_ReflectionFiber_getTrace, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_ReflectionException(zend_class_entry *class_entry_Exception)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
@ -1364,3 +1399,14 @@ static zend_class_entry *register_class_ReflectionEnumBackedCase(zend_class_entr
|
|||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
static zend_class_entry *register_class_ReflectionFiber(void)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "ReflectionFiber", class_ReflectionFiber_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, NULL);
|
||||
class_entry->ce_flags |= ZEND_ACC_FINAL;
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue