Skip to content

Commit 47e93b9

Browse files
committed
Clean up guts of hidden command invoking to shorten code paths; TclObjInvoke remains for stubs compat only
2 parents 807addf + 36a97fa commit 47e93b9

File tree

4 files changed

+36
-84
lines changed

4 files changed

+36
-84
lines changed

generic/tclBasic.c

Lines changed: 8 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6619,61 +6619,14 @@ Tcl_ExprBooleanObj(
66196619
return result;
66206620
}
66216621

6622-
/*
6623-
*----------------------------------------------------------------------
6624-
*
6625-
* TclObjInvokeNamespace --
6626-
*
6627-
* Object version: Invokes a Tcl command, given an objv/objc, from either
6628-
* the exposed or hidden set of commands in the given interpreter.
6629-
*
6630-
* NOTE: The command is invoked in the global stack frame of the
6631-
* interpreter or namespace, thus it cannot see any current state on the
6632-
* stack of that interpreter.
6633-
*
6634-
* Results:
6635-
* A standard Tcl result.
6636-
*
6637-
* Side effects:
6638-
* Whatever the command does.
6639-
*
6640-
*----------------------------------------------------------------------
6641-
*/
6642-
6643-
int
6644-
TclObjInvokeNamespace(
6645-
Tcl_Interp *interp, /* Interpreter in which command is to be
6646-
* invoked. */
6647-
Tcl_Size objc, /* Count of arguments. */
6648-
Tcl_Obj *const objv[], /* Argument objects; objv[0] points to the
6649-
* name of the command to invoke. */
6650-
Tcl_Namespace *nsPtr, /* The namespace to use. */
6651-
int flags) /* Combination of flags controlling the call:
6652-
* TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
6653-
* or TCL_INVOKE_NO_TRACEBACK. */
6654-
{
6655-
int result;
6656-
Tcl_CallFrame *framePtr;
6657-
6658-
/*
6659-
* Make the specified namespace the current namespace and invoke the
6660-
* command.
6661-
*/
6662-
6663-
(void) TclPushStackFrame(interp, &framePtr, nsPtr, /*isProcFrame*/0);
6664-
result = TclObjInvoke(interp, objc, objv, flags);
6665-
6666-
TclPopStackFrame(interp);
6667-
return result;
6668-
}
6669-
66706622
/*
66716623
*----------------------------------------------------------------------
66726624
*
66736625
* TclObjInvoke --
66746626
*
6675-
* Invokes a Tcl command, given an objv/objc, from either the exposed or
6676-
* the hidden sets of commands in the given interpreter.
6627+
* Invokes a Tcl command, given an objv/objc, from the hidden set of
6628+
* commands in the given interpreter. Only supported for calls via
6629+
* "internal" stub table.
66776630
*
66786631
* Results:
66796632
* A standard Tcl object result.
@@ -6693,7 +6646,9 @@ TclObjInvoke(
66936646
* name of the command to invoke. */
66946647
int flags) /* Combination of flags controlling the call:
66956648
* TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
6696-
* or TCL_INVOKE_NO_TRACEBACK. */
6649+
* or TCL_INVOKE_NO_TRACEBACK. Only
6650+
* TCL_INVOKE_HIDDEN is now supported, and
6651+
* must be supplied. */
66976652
{
66986653
if (interp == NULL) {
66996654
return TCL_ERROR;
@@ -6703,8 +6658,8 @@ TclObjInvoke(
67036658
"illegal argument vector", TCL_INDEX_NONE));
67046659
return TCL_ERROR;
67056660
}
6706-
if ((flags & TCL_INVOKE_HIDDEN) == 0) {
6707-
Tcl_Panic("TclObjInvoke: called without TCL_INVOKE_HIDDEN");
6661+
if (flags != TCL_INVOKE_HIDDEN) {
6662+
Tcl_Panic("TclObjInvoke: called without just TCL_INVOKE_HIDDEN");
67086663
}
67096664
return Tcl_NRCallObjProc(interp, TclNRInvoke, NULL, objc, objv);
67106665
}

generic/tclEvent.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ TclDefaultBgErrorHandlerObjCmd(
461461

462462
if (Tcl_IsSafe(interp)) {
463463
Tcl_RestoreInterpState(interp, saved);
464-
TclObjInvoke(interp, 2, tempObjv, TCL_INVOKE_HIDDEN);
464+
Tcl_NRCallObjProc(interp, TclNRInvoke, NULL, 2, tempObjv);
465465
} else {
466466
Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
467467

generic/tclInt.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,19 +2542,15 @@ typedef enum TclEolTranslation {
25422542
} TclEolTranslation;
25432543

25442544
/*
2545-
* Flags for TclInvoke:
2545+
* Obsolete: flags for TclObjInvoke. Only TCL_INVOKE_HIDDEN was supported at
2546+
* all in 9.0, and then just as something to Tcl_Panic over if not given.
25462547
*/
25472548
enum TclInvokeFlags {
2548-
TCL_INVOKE_HIDDEN = 1, /* Invoke a hidden command; if not set, invokes
2549-
* an exposed command. */
2549+
TCL_INVOKE_HIDDEN = 1, /* Invoke a hidden command. */
25502550
TCL_INVOKE_NO_UNKNOWN = 2, /* "unknown" is not invoked if the command to
2551-
* be invoked is not found. Only has an effect
2552-
* if invoking an exposed command, i.e. if
2553-
* TCL_INVOKE_HIDDEN is not also set. */
2554-
TCL_INVOKE_NO_TRACEBACK = 4 /* Does not record traceback information if the
2555-
* invoked command returns an error. Used if the
2556-
* caller plans on recording its own traceback
2557-
* information. */
2551+
* be invoked is not found. */
2552+
TCL_INVOKE_NO_TRACEBACK = 4 /* Do not record traceback information if the
2553+
* invoked command returns an error. */
25582554
};
25592555

25602556
/*
@@ -3520,9 +3516,6 @@ MODULE_SCOPE int TclNamespaceDeleted(Namespace *nsPtr);
35203516
MODULE_SCOPE void TclObjVarErrMsg(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
35213517
Tcl_Obj *part2Ptr, const char *operation,
35223518
const char *reason, Tcl_Size index);
3523-
MODULE_SCOPE int TclObjInvokeNamespace(Tcl_Interp *interp,
3524-
Tcl_Size objc, Tcl_Obj *const objv[],
3525-
Tcl_Namespace *nsPtr, int flags);
35263519
MODULE_SCOPE int TclObjUnsetVar2(Tcl_Interp *interp,
35273520
Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags);
35283521
MODULE_SCOPE Tcl_Size TclParseBackslash(const char *src,

generic/tclInterp.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,8 +3160,6 @@ ChildInvokeHidden(
31603160
Tcl_Size objc, /* Number of arguments. */
31613161
Tcl_Obj *const objv[]) /* Argument objects. */
31623162
{
3163-
int result;
3164-
31653163
if (Tcl_IsSafe(interp)) {
31663164
Tcl_SetObjResult(interp, Tcl_NewStringObj(
31673165
"not allowed to invoke hidden commands from safe interpreter",
@@ -3170,33 +3168,35 @@ ChildInvokeHidden(
31703168
(char *)NULL);
31713169
return TCL_ERROR;
31723170
}
3171+
if (objc < 1) {
3172+
Tcl_Panic("need at least one word: hidden command name");
3173+
}
31733174

31743175
Tcl_Preserve(childInterp);
31753176
Tcl_AllowExceptions(childInterp);
31763177

3177-
if (namespaceName == NULL) {
3178-
NRE_callback *rootPtr = TOP_CB(childInterp);
3179-
3180-
Tcl_NRAddCallback(interp, NRPostInvokeHidden, childInterp,
3181-
rootPtr, NULL, NULL);
3182-
return TclNRInvoke(NULL, childInterp, objc, objv);
3183-
} else {
3178+
// Push the namespace if one has been requested.
3179+
Tcl_CallFrame *framePtr = NULL;
3180+
if (namespaceName != NULL) {
31843181
Namespace *nsPtr, *dummy1, *dummy2;
31853182
const char *tail;
31863183

3187-
result = TclGetNamespaceForQualName(childInterp, namespaceName, NULL,
3184+
int result = TclGetNamespaceForQualName(childInterp, namespaceName, NULL,
31883185
TCL_FIND_ONLY_NS | TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG
31893186
| TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
3190-
if (result == TCL_OK) {
3191-
result = TclObjInvokeNamespace(childInterp, objc, objv,
3192-
(Tcl_Namespace *) nsPtr, TCL_INVOKE_HIDDEN);
3187+
if (result != TCL_OK) {
3188+
Tcl_TransferResult(childInterp, result, interp);
3189+
Tcl_Release(childInterp);
3190+
return result;
31933191
}
3194-
}
31953192

3196-
Tcl_TransferResult(childInterp, result, interp);
3193+
(void) TclPushStackFrame(childInterp, &framePtr, (Tcl_Namespace *) nsPtr,
3194+
/*isProcFrame*/ 0);
3195+
}
31973196

3198-
Tcl_Release(childInterp);
3199-
return result;
3197+
Tcl_NRAddCallback(interp, NRPostInvokeHidden, childInterp,
3198+
TOP_CB(childInterp), framePtr, NULL);
3199+
return TclNRInvoke(NULL, childInterp, objc, objv);
32003200
}
32013201

32023202
static int
@@ -3207,11 +3207,15 @@ NRPostInvokeHidden(
32073207
{
32083208
Tcl_Interp *childInterp = (Tcl_Interp *) data[0];
32093209
NRE_callback *rootPtr = (NRE_callback *) data[1];
3210+
CallFrame *framePtr = (CallFrame *) data[2];
32103211

32113212
if (interp != childInterp) {
32123213
result = TclNRRunCallbacks(childInterp, result, rootPtr);
32133214
Tcl_TransferResult(childInterp, result, interp);
32143215
}
3216+
if (framePtr) {
3217+
TclPopStackFrame(childInterp);
3218+
}
32153219
Tcl_Release(childInterp);
32163220
return result;
32173221
}

0 commit comments

Comments
 (0)