summaryrefslogtreecommitdiffstats
path: root/nsprpub/pr/src/md/windows/ntgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'nsprpub/pr/src/md/windows/ntgc.c')
-rw-r--r--nsprpub/pr/src/md/windows/ntgc.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/nsprpub/pr/src/md/windows/ntgc.c b/nsprpub/pr/src/md/windows/ntgc.c
new file mode 100644
index 0000000000..20ad8a81e4
--- /dev/null
+++ b/nsprpub/pr/src/md/windows/ntgc.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * GC related routines
+ *
+ */
+#include <windows.h>
+#include "primpl.h"
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#if defined(_X86_)
+ CONTEXT context;
+ context.ContextFlags = CONTEXT_INTEGER;
+
+ if (_PR_IS_NATIVE_THREAD(t)) {
+ context.ContextFlags |= CONTEXT_CONTROL;
+ if (GetThreadContext(t->md.handle, &context)) {
+ t->md.gcContext[0] = context.Eax;
+ t->md.gcContext[1] = context.Ebx;
+ t->md.gcContext[2] = context.Ecx;
+ t->md.gcContext[3] = context.Edx;
+ t->md.gcContext[4] = context.Esi;
+ t->md.gcContext[5] = context.Edi;
+ t->md.gcContext[6] = context.Esp;
+ t->md.gcContext[7] = context.Ebp;
+ *np = PR_NUM_GCREGS;
+ } else {
+ PR_ASSERT(0);/* XXX */
+ }
+ } else {
+ /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * This code is extremely machine dependant and completely
+ * undocumented by MS. Its only known to work experimentally.
+ * Ready for a walk on the wild * side?
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
+
+#if !defined WIN95 // Win95 does not have fibers
+ int *fiberData = t->md.fiber_id;
+
+ /* I found these offsets by disassembling SwitchToFiber().
+ * Are your palms sweating yet?
+ */
+
+ /*
+ ** EAX is on the stack (ESP+0)
+ ** EDX is on the stack (ESP+4)
+ ** ECX is on the stack (ESP+8)
+ */
+ t->md.gcContext[0] = 0; /* context.Eax */
+ t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */
+ t->md.gcContext[2] = 0; /* context.Ecx */
+ t->md.gcContext[3] = 0; /* context.Edx */
+ t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */
+ t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */
+ t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */
+ t->md.gcContext[7] = fiberData[0x32]; /* context.Ebp */
+ *np = PR_NUM_GCREGS;
+#endif
+ }
+ return (PRWord *)&t->md.gcContext;
+#else
+ PR_NOT_REACHED("not implemented");
+ return NULL;
+#endif /* defined(_X86_) */
+}
+
+/* This function is not used right now, but is left as a reference.
+ * If you ever need to get the fiberID from the currently running fiber,
+ * this is it.
+ */
+void *
+GetMyFiberID()
+{
+#if defined(_X86_) && !defined(__MINGW32__)
+ void *fiberData;
+
+ /* A pointer to our tib entry is found at FS:[18]
+ * At offset 10h is the fiberData pointer. The context of the
+ * fiber is stored in there.
+ */
+ __asm {
+ mov EDX, FS:[18h]
+ mov EAX, DWORD PTR [EDX+10h]
+ mov [fiberData], EAX
+ }
+
+ return fiberData;
+#else
+ PR_NOT_REACHED("not implemented");
+ return NULL;
+#endif /* defined(_X86_) */
+}