OSDN Git Service

Updated to tcl 8.4.1
[pf3gnuchains/pf3gnuchains3x.git] / tcl / win / tclWin32Dll.c
index 6599894..6394e0e 100644 (file)
@@ -37,6 +37,11 @@ typedef VOID (WINAPI UTUNREGISTER)(HANDLE hModule);
 static HINSTANCE hInstance;    /* HINSTANCE of this DLL. */
 static int platformId;         /* Running under NT, or 95/98? */
 
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
 /*
  * The following function tables are used to dispatch to either the
  * wide-character or multi-byte versions of the operating system calls,
@@ -78,6 +83,8 @@ static TclWinProcs asciiProcs = {
            WCHAR *, TCHAR **)) SearchPathA,
     (BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryA,
     (BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesA,
+    NULL,
+    NULL,
 };
 
 static TclWinProcs unicodeProcs = {
@@ -115,10 +122,12 @@ static TclWinProcs unicodeProcs = {
            WCHAR *, TCHAR **)) SearchPathW,
     (BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryW,
     (BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesW,
+    NULL,
+    NULL,
 };
 
 TclWinProcs *tclWinProcs;
-Tcl_Encoding tclWinTCharEncoding;
+static Tcl_Encoding tclWinTCharEncoding;
 
 /*
  * The following declaration is for the VC++ DLL entry point.
@@ -127,14 +136,6 @@ Tcl_Encoding tclWinTCharEncoding;
 BOOL APIENTRY          DllMain(HINSTANCE hInst, DWORD reason, 
                                LPVOID reserved);
 
-/* CYGNUS LOCAL */
-#ifdef __CYGWIN__0
-/* CYGWIN requires an impure pointer variable, which must be
-   explicitly initialized when the DLL starts up.  */
-struct _reent *_impure_ptr;
-extern struct _reent __declspec(dllimport) reent_data;
-#endif
-/* END CYGNUS LOCAL */
 
 #ifdef __WIN32__
 #ifndef STATIC_BUILD
@@ -190,14 +191,6 @@ DllMain(hInst, reason, reserved)
     DWORD reason;              /* Reason this function is being called. */
     LPVOID reserved;           /* Not used. */
 {
-    /* CYGNUS LOCAL */
-#ifdef __CYGWIN__0
-    /* Cygwin requires the impure data pointer to be initialized
-       when the DLL starts up.  */
-    _impure_ptr = &reent_data;
-#endif
-    /* END CYGNUS LOCAL */
-
     switch (reason) {
     case DLL_PROCESS_ATTACH:
        TclWinInit(hInst);
@@ -354,6 +347,8 @@ TclWinNoBackslash(
 int
 TclpCheckStackSpace()
 {
+    int retval = 0;
+
     /*
      * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD
      * bytes of stack space left.  alloca() is cheap on windows; basically
@@ -361,19 +356,56 @@ TclpCheckStackSpace()
      * exception if the stack pointer is set below the bottom of the stack.
      */
 
-#ifndef __GNUC__
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "movl  %esp, _ESP" "\n\t"
+            "movl  %ebp, _EBP");
+
+    __asm__ __volatile__ (
+            "pushl $__except_checkstackspace_handler" "\n\t"
+            "pushl %fs:0" "\n\t"
+            "mov   %esp, %fs:0");
+#else
     __try {
+#endif /* HAVE_NO_SEH */
        alloca(TCL_WIN_STACK_THRESHOLD);
-       return 1;
-    /* CYGNUS LOCAL */
-    } __except (1) {}
+       retval = 1;
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "jmp   checkstackspace_pop" "\n"
+            "checkstackspace_reentry:" "\n\t"
+            "movl  _ESP, %esp" "\n\t"
+            "movl  _EBP, %ebp");
+
+    __asm__ __volatile__ (
+            "checkstackspace_pop:" "\n\t"
+            "mov   (%esp), %eax" "\n\t"
+            "mov   %eax, %fs:0" "\n\t"
+            "add   $8, %esp");
 #else
-    return alloca(TCL_WIN_STACK_THRESHOLD) != NULL;
-#endif
+    } __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
 
-    return 0;
+    /*
+     * Avoid using control flow statements in the SEH guarded block!
+     */
+    return retval;
 }
-
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_checkstackspace_handler(
+    struct _EXCEPTION_RECORD *ExceptionRecord,
+    void *EstablisherFrame,
+    struct _CONTEXT *ContextRecord,
+    void *DispatcherContext)
+{
+    __asm__ __volatile__ (
+            "jmp checkstackspace_reentry");
+    return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
 \f
 /*
  *----------------------------------------------------------------------
@@ -407,6 +439,10 @@ TclWinGetPlatform()
  *     tclWinProcs structure to dispatch to either the wide-character
  *     or multi-byte versions of the operating system calls, depending
  *     on whether Unicode is the system encoding.
+ *     
+ *     As well as this, we can also try to load in some additional
+ *     procs which may/may not be present depending on the current
+ *     Windows version (e.g. Win95 will not have the procs below).
  *
  * Results:
  *     None.
@@ -427,9 +463,35 @@ TclWinSetInterfaces(
     if (wide) {
        tclWinProcs = &unicodeProcs;
        tclWinTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
+       if (tclWinProcs->getFileAttributesExProc == NULL) {
+           HINSTANCE hInstance = LoadLibraryA("kernel32");
+           if (hInstance != NULL) {
+               tclWinProcs->getFileAttributesExProc = 
+                 (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS, 
+                 LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExW");
+               tclWinProcs->createHardLinkProc = 
+                 (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*, 
+                 LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance, 
+                 "CreateHardLinkW");
+               FreeLibrary(hInstance);
+           }
+       }
     } else {
        tclWinProcs = &asciiProcs;
        tclWinTCharEncoding = NULL;
+       if (tclWinProcs->getFileAttributesExProc == NULL) {
+           HINSTANCE hInstance = LoadLibraryA("kernel32");
+           if (hInstance != NULL) {
+               tclWinProcs->getFileAttributesExProc = 
+                 (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS, 
+                 LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExA");
+               tclWinProcs->createHardLinkProc = 
+                 (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*, 
+                 LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance, 
+                 "CreateHardLinkA");
+               FreeLibrary(hInstance);
+           }
+       }
     }
 }
 \f
@@ -511,6 +573,3 @@ Tcl_WinTCharToUtf(string, len, dsPtr)
     return Tcl_ExternalToUtfDString(tclWinTCharEncoding, 
            (CONST char *) string, len, dsPtr);
 }
-
-
-