Fossil SCM
Minor cleanup of Tcl integration code. Also, add more comments describing USE_TCL_EVALOBJV.
Commit
d7f83e7462c75e04fdb7cf05e72a5820641f6ad5
Parent
5782fa032e1b67a…
1 file changed
+25
-3
+25
-3
| --- src/th_tcl.c | ||
| +++ src/th_tcl.c | ||
| @@ -29,19 +29,38 @@ | ||
| 29 | 29 | ** Has the decision about whether or not to use Tcl_EvalObjv already been made |
| 30 | 30 | ** via the Makefile? |
| 31 | 31 | */ |
| 32 | 32 | #if !defined(USE_TCL_EVALOBJV) |
| 33 | 33 | /* |
| 34 | -** Are we being compiled against Tcl 8.6 or higher? | |
| 34 | +** Are we being compiled against Tcl 8.6 or higher? This check is [mostly] | |
| 35 | +** wrong for at least the following two reasons: | |
| 36 | +** | |
| 37 | +** 1. This check assumes that all versions of Tcl 8.6 and higher suffer from | |
| 38 | +** the issue described in SF bug #3399564, which is incorrect. | |
| 39 | +** | |
| 40 | +** 2. Technically, this check is completely useless when the stubs mechanism | |
| 41 | +** is in use. In that case, a runtime version check would be required and | |
| 42 | +** that has not been implemented. | |
| 43 | +** | |
| 44 | +** However, if a particular user compiles and runs against Tcl 8.6 (or later), | |
| 45 | +** this will cause a fallback to using the "conservative" method of directly | |
| 46 | +** invoking a Tcl command. In that case, potential crashes will be avoided if | |
| 47 | +** the user just so happened to compile or run against a late beta of Tcl 8.6. | |
| 35 | 48 | */ |
| 36 | 49 | #if (TCL_MAJOR_VERSION > 8) || \ |
| 37 | 50 | ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 6)) |
| 38 | 51 | /* |
| 39 | 52 | ** Workaround NRE-specific issue in Tcl_EvalObjCmd (SF bug #3399564) by using |
| 40 | 53 | ** Tcl_EvalObjv instead of invoking the objProc directly. |
| 41 | 54 | */ |
| 42 | -# define USE_TCL_EVALOBJV 1 | |
| 55 | +# define USE_TCL_EVALOBJV (1) | |
| 56 | +#else | |
| 57 | +/* | |
| 58 | +** We should be able to safely use Tcl_GetCommandInfoFromToken, when the need | |
| 59 | +** arises, to invoke a specific Tcl command "directly" with some arguments. | |
| 60 | + */ | |
| 61 | +# define USE_TCL_EVALOBJV (0) | |
| 43 | 62 | #endif /* (TCL_MAJOR_VERSION > 8) ... */ |
| 44 | 63 | #endif /* !defined(USE_TCL_EVALOBJV) */ |
| 45 | 64 | |
| 46 | 65 | /* |
| 47 | 66 | ** These macros are designed to reduce the redundant code required to marshal |
| @@ -769,25 +788,28 @@ | ||
| 769 | 788 | } |
| 770 | 789 | #if defined(USE_TCL_STUBS) |
| 771 | 790 | #if defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) |
| 772 | 791 | if( initTclStubs(interp, tclInterp)!=TH_OK ){ |
| 773 | 792 | tclContext->xDeleteInterp(tclInterp); |
| 793 | + tclInterp = 0; | |
| 774 | 794 | return TH_ERROR; |
| 775 | 795 | } |
| 776 | 796 | #else |
| 777 | 797 | if( !Tcl_InitStubs(tclInterp, "8.4", 0) ){ |
| 778 | 798 | Th_ErrorMessage(interp, |
| 779 | 799 | "could not initialize Tcl stubs", (const char *)"", 0); |
| 780 | 800 | tclContext->xDeleteInterp(tclInterp); |
| 801 | + tclInterp = 0; | |
| 781 | 802 | return TH_ERROR; |
| 782 | 803 | } |
| 783 | 804 | #endif /* defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) */ |
| 784 | 805 | #endif /* defined(USE_TCL_STUBS) */ |
| 785 | 806 | if( Tcl_InterpDeleted(tclInterp) ){ |
| 786 | 807 | Th_ErrorMessage(interp, |
| 787 | 808 | "Tcl interpreter appears to be deleted", (const char *)"", 0); |
| 788 | - tclContext->xDeleteInterp(tclInterp); /* TODO: Redundant? */ | |
| 809 | + Tcl_DeleteInterp(tclInterp); /* TODO: Redundant? */ | |
| 810 | + tclInterp = 0; | |
| 789 | 811 | return TH_ERROR; |
| 790 | 812 | } |
| 791 | 813 | tclContext->interp = tclInterp; |
| 792 | 814 | if( Tcl_Init(tclInterp)!=TCL_OK ){ |
| 793 | 815 | Th_ErrorMessage(interp, |
| 794 | 816 |
| --- src/th_tcl.c | |
| +++ src/th_tcl.c | |
| @@ -29,19 +29,38 @@ | |
| 29 | ** Has the decision about whether or not to use Tcl_EvalObjv already been made |
| 30 | ** via the Makefile? |
| 31 | */ |
| 32 | #if !defined(USE_TCL_EVALOBJV) |
| 33 | /* |
| 34 | ** Are we being compiled against Tcl 8.6 or higher? |
| 35 | */ |
| 36 | #if (TCL_MAJOR_VERSION > 8) || \ |
| 37 | ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 6)) |
| 38 | /* |
| 39 | ** Workaround NRE-specific issue in Tcl_EvalObjCmd (SF bug #3399564) by using |
| 40 | ** Tcl_EvalObjv instead of invoking the objProc directly. |
| 41 | */ |
| 42 | # define USE_TCL_EVALOBJV 1 |
| 43 | #endif /* (TCL_MAJOR_VERSION > 8) ... */ |
| 44 | #endif /* !defined(USE_TCL_EVALOBJV) */ |
| 45 | |
| 46 | /* |
| 47 | ** These macros are designed to reduce the redundant code required to marshal |
| @@ -769,25 +788,28 @@ | |
| 769 | } |
| 770 | #if defined(USE_TCL_STUBS) |
| 771 | #if defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) |
| 772 | if( initTclStubs(interp, tclInterp)!=TH_OK ){ |
| 773 | tclContext->xDeleteInterp(tclInterp); |
| 774 | return TH_ERROR; |
| 775 | } |
| 776 | #else |
| 777 | if( !Tcl_InitStubs(tclInterp, "8.4", 0) ){ |
| 778 | Th_ErrorMessage(interp, |
| 779 | "could not initialize Tcl stubs", (const char *)"", 0); |
| 780 | tclContext->xDeleteInterp(tclInterp); |
| 781 | return TH_ERROR; |
| 782 | } |
| 783 | #endif /* defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) */ |
| 784 | #endif /* defined(USE_TCL_STUBS) */ |
| 785 | if( Tcl_InterpDeleted(tclInterp) ){ |
| 786 | Th_ErrorMessage(interp, |
| 787 | "Tcl interpreter appears to be deleted", (const char *)"", 0); |
| 788 | tclContext->xDeleteInterp(tclInterp); /* TODO: Redundant? */ |
| 789 | return TH_ERROR; |
| 790 | } |
| 791 | tclContext->interp = tclInterp; |
| 792 | if( Tcl_Init(tclInterp)!=TCL_OK ){ |
| 793 | Th_ErrorMessage(interp, |
| 794 |
| --- src/th_tcl.c | |
| +++ src/th_tcl.c | |
| @@ -29,19 +29,38 @@ | |
| 29 | ** Has the decision about whether or not to use Tcl_EvalObjv already been made |
| 30 | ** via the Makefile? |
| 31 | */ |
| 32 | #if !defined(USE_TCL_EVALOBJV) |
| 33 | /* |
| 34 | ** Are we being compiled against Tcl 8.6 or higher? This check is [mostly] |
| 35 | ** wrong for at least the following two reasons: |
| 36 | ** |
| 37 | ** 1. This check assumes that all versions of Tcl 8.6 and higher suffer from |
| 38 | ** the issue described in SF bug #3399564, which is incorrect. |
| 39 | ** |
| 40 | ** 2. Technically, this check is completely useless when the stubs mechanism |
| 41 | ** is in use. In that case, a runtime version check would be required and |
| 42 | ** that has not been implemented. |
| 43 | ** |
| 44 | ** However, if a particular user compiles and runs against Tcl 8.6 (or later), |
| 45 | ** this will cause a fallback to using the "conservative" method of directly |
| 46 | ** invoking a Tcl command. In that case, potential crashes will be avoided if |
| 47 | ** the user just so happened to compile or run against a late beta of Tcl 8.6. |
| 48 | */ |
| 49 | #if (TCL_MAJOR_VERSION > 8) || \ |
| 50 | ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 6)) |
| 51 | /* |
| 52 | ** Workaround NRE-specific issue in Tcl_EvalObjCmd (SF bug #3399564) by using |
| 53 | ** Tcl_EvalObjv instead of invoking the objProc directly. |
| 54 | */ |
| 55 | # define USE_TCL_EVALOBJV (1) |
| 56 | #else |
| 57 | /* |
| 58 | ** We should be able to safely use Tcl_GetCommandInfoFromToken, when the need |
| 59 | ** arises, to invoke a specific Tcl command "directly" with some arguments. |
| 60 | */ |
| 61 | # define USE_TCL_EVALOBJV (0) |
| 62 | #endif /* (TCL_MAJOR_VERSION > 8) ... */ |
| 63 | #endif /* !defined(USE_TCL_EVALOBJV) */ |
| 64 | |
| 65 | /* |
| 66 | ** These macros are designed to reduce the redundant code required to marshal |
| @@ -769,25 +788,28 @@ | |
| 788 | } |
| 789 | #if defined(USE_TCL_STUBS) |
| 790 | #if defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) |
| 791 | if( initTclStubs(interp, tclInterp)!=TH_OK ){ |
| 792 | tclContext->xDeleteInterp(tclInterp); |
| 793 | tclInterp = 0; |
| 794 | return TH_ERROR; |
| 795 | } |
| 796 | #else |
| 797 | if( !Tcl_InitStubs(tclInterp, "8.4", 0) ){ |
| 798 | Th_ErrorMessage(interp, |
| 799 | "could not initialize Tcl stubs", (const char *)"", 0); |
| 800 | tclContext->xDeleteInterp(tclInterp); |
| 801 | tclInterp = 0; |
| 802 | return TH_ERROR; |
| 803 | } |
| 804 | #endif /* defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) */ |
| 805 | #endif /* defined(USE_TCL_STUBS) */ |
| 806 | if( Tcl_InterpDeleted(tclInterp) ){ |
| 807 | Th_ErrorMessage(interp, |
| 808 | "Tcl interpreter appears to be deleted", (const char *)"", 0); |
| 809 | Tcl_DeleteInterp(tclInterp); /* TODO: Redundant? */ |
| 810 | tclInterp = 0; |
| 811 | return TH_ERROR; |
| 812 | } |
| 813 | tclContext->interp = tclInterp; |
| 814 | if( Tcl_Init(tclInterp)!=TCL_OK ){ |
| 815 | Th_ErrorMessage(interp, |
| 816 |