| OLD | NEW |
| (Empty) |
| 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
| 2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 5 | |
| 6 /* | |
| 7 * GC related routines | |
| 8 * | |
| 9 */ | |
| 10 #include <windows.h> | |
| 11 #include "primpl.h" | |
| 12 | |
| 13 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) | |
| 14 { | |
| 15 #if defined(_X86_) | |
| 16 CONTEXT context; | |
| 17 context.ContextFlags = CONTEXT_INTEGER; | |
| 18 | |
| 19 if (_PR_IS_NATIVE_THREAD(t)) { | |
| 20 context.ContextFlags |= CONTEXT_CONTROL; | |
| 21 if (GetThreadContext(t->md.handle, &context)) { | |
| 22 t->md.gcContext[0] = context.Eax; | |
| 23 t->md.gcContext[1] = context.Ebx; | |
| 24 t->md.gcContext[2] = context.Ecx; | |
| 25 t->md.gcContext[3] = context.Edx; | |
| 26 t->md.gcContext[4] = context.Esi; | |
| 27 t->md.gcContext[5] = context.Edi; | |
| 28 t->md.gcContext[6] = context.Esp; | |
| 29 t->md.gcContext[7] = context.Ebp; | |
| 30 *np = PR_NUM_GCREGS; | |
| 31 } else { | |
| 32 PR_ASSERT(0);/* XXX */ | |
| 33 } | |
| 34 } else { | |
| 35 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING | |
| 36 * | |
| 37 * This code is extremely machine dependant and completely | |
| 38 * undocumented by MS. Its only known to work experimentally. | |
| 39 * Ready for a walk on the wild * side? | |
| 40 * | |
| 41 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ | |
| 42 | |
| 43 #if !defined WIN95 // Win95 does not have fibers | |
| 44 int *fiberData = t->md.fiber_id; | |
| 45 | |
| 46 /* I found these offsets by disassembling SwitchToFiber(). | |
| 47 * Are your palms sweating yet? | |
| 48 */ | |
| 49 | |
| 50 /* | |
| 51 ** EAX is on the stack (ESP+0) | |
| 52 ** EDX is on the stack (ESP+4) | |
| 53 ** ECX is on the stack (ESP+8) | |
| 54 */ | |
| 55 t->md.gcContext[0] = 0; /* context.Eax */ | |
| 56 t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */ | |
| 57 t->md.gcContext[2] = 0; /* context.Ecx */ | |
| 58 t->md.gcContext[3] = 0; /* context.Edx */ | |
| 59 t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */ | |
| 60 t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */ | |
| 61 t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */ | |
| 62 t->md.gcContext[7] = fiberData[0x32]; /* context.Ebp */ | |
| 63 *np = PR_NUM_GCREGS; | |
| 64 #endif | |
| 65 } | |
| 66 return (PRWord *)&t->md.gcContext; | |
| 67 #else | |
| 68 PR_NOT_REACHED("not implemented"); | |
| 69 return NULL; | |
| 70 #endif /* defined(_X86_) */ | |
| 71 } | |
| 72 | |
| 73 /* This function is not used right now, but is left as a reference. | |
| 74 * If you ever need to get the fiberID from the currently running fiber, | |
| 75 * this is it. | |
| 76 */ | |
| 77 void * | |
| 78 GetMyFiberID() | |
| 79 { | |
| 80 #if defined(_X86_) && !defined(__MINGW32__) | |
| 81 void *fiberData; | |
| 82 | |
| 83 /* A pointer to our tib entry is found at FS:[18] | |
| 84 * At offset 10h is the fiberData pointer. The context of the | |
| 85 * fiber is stored in there. | |
| 86 */ | |
| 87 __asm { | |
| 88 mov EDX, FS:[18h] | |
| 89 mov EAX, DWORD PTR [EDX+10h] | |
| 90 mov [fiberData], EAX | |
| 91 } | |
| 92 | |
| 93 return fiberData; | |
| 94 #else | |
| 95 PR_NOT_REACHED("not implemented"); | |
| 96 return NULL; | |
| 97 #endif /* defined(_X86_) */ | |
| 98 } | |
| OLD | NEW |