diff options
Diffstat (limited to 'private/crt32/misc/i386/setjmp3.asm')
-rw-r--r-- | private/crt32/misc/i386/setjmp3.asm | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/private/crt32/misc/i386/setjmp3.asm b/private/crt32/misc/i386/setjmp3.asm new file mode 100644 index 000000000..9c03e9a8c --- /dev/null +++ b/private/crt32/misc/i386/setjmp3.asm @@ -0,0 +1,148 @@ +;*** +;setjmp3.asm +; +; Copyright (C) 1994 Microsoft Corporation. All rights reserved. +; +;Purpose: +; Contains setjmp(), longjmp() & raisex() routines; +; split from exsup.asm for granularity purposes. +; +;Notes: +; +;Revision History: +; 01-12-94 PML Split from setjmp.asm, added C9.0 generic EH +; callback for unwind. +; 02-10-94 GJF -1 is the end-of-exception-handler chain marker, not +; 0. +; +;******************************************************************************* + +;hnt = -D_WIN32_ -Dsmall32 -Dflat32 -Mx $this; + +;Define small32 and flat32 since these are not defined in the NT build process +small32 equ 1 +flat32 equ 1 + +.xlist +include pversion.inc +?DFDATA = 1 +?NODATA = 1 +include cmacros.mas +include exsup.inc +.list + +assumes DS,DATA +assumes FS,DATA + +BeginCODE +if @Version LT 600 +;this needs to go here to work around a masm5 bug. (emits wrong fixup) +assumes CS,FLAT +endif + +; Following symbol defined in exsup.asm +extrn __except_list:near + +; int +; _setjmp3 ( +; OUT jmp_buf env, +; int count, +; ...) +; +; Routine Description: +; +; (New) implementation of setjmp intrinsic. Saves the current +; nonvolatile register state in the specified jump buffer and returns +; a function value of zero. +; +; Saves the callee-save registers, stack pointer and return address. +; Also saves the exception registration list head. If setjmp is +; called from a function using any form of exception handling, then +; additional data is also saved allowing some form of local unwind +; at longjmp time to restore the proper exception handling state. +; +; Arguments: +; +; env - Address of the buffer for storing the state information +; count - count of additional DWORDs of information. Zero if setjmp +; not called from a function with any form of EH. +; ... Additional data pushed by the setjmp intrinsic if called +; from a function with any form of EH. The first DWORD is +; a function ptr which will be called at longjmp time to do +; the local unwind. The second DWORD is the try level to be +; restored (if applicable). Any further data is saved in the +; generic data array in the jmp_buf for use by the local +; unwind function. +; +; Return Value: +; +; A value of zero is returned. + +public __setjmp3 +__setjmp3 PROC NEAR + mov edx, [esp+4] + mov [edx.saved_ebp], ebp ; old bp and the rest + mov [edx.saved_ebx], ebx + mov [edx.saved_edi], edi + mov [edx.saved_esi], esi + mov [edx.saved_esp], esp + + mov eax, [esp] ; return address + mov [edx.saved_return], eax + + mov dword ptr [edx.version_cookie], JMPBUF_COOKIE + mov dword ptr [edx.unwind_func], 0 + + mov eax, dword ptr fs:__except_list + mov [edx.saved_xregistration], eax + + cmp eax, -1 ; -1 means no higher-level handler + jnz short _s3_get_count + mov dword ptr [edx.saved_trylevel], -1 ;something invalid + jmp short _s3_done + +_s3_get_count: + mov ecx, [esp+8] ; count of additional data + or ecx, ecx + jz short _s3_default_trylevel + + mov eax, [esp+12] ; func to do local unwind at longjmp + mov [edx.unwind_func], eax + dec ecx + jnz _s3_save_trylevel + + ; Not called from a function with any form of EH, or no trylevel + ; passed. Save the TryLevel from the topmost EH node anyway, + ; assuming a C8.0 SEH node. If we're linked to an obsolete CRTDLL + ; and call the old longjmp, then we'll still do the right thing. +_s3_default_trylevel: + mov eax, [eax + C8_TRYLEVEL] + mov [edx.saved_trylevel], eax + jmp short _s3_done + +_s3_save_trylevel: + mov eax, [esp+16] ; try level to unwind to + mov [edx.saved_trylevel], eax + dec ecx + jz short _s3_done + + push esi + push edi + lea esi, [esp+20+8] + lea edi, [edx.unwind_data] + cmp ecx, 6 ; save up to 6 more DWORDs in jmp_buf + jbe _s3_save_data + mov ecx, 6 + +_s3_save_data: + rep movsd + pop edi + pop esi + +_s3_done: + sub eax, eax + ret +__setjmp3 ENDP + +EndCODE +END |