os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclProc.c
Update contrib.
4 * This file contains routines that implement Tcl procedures,
5 * including the "proc" and "uplevel" commands.
7 * Copyright (c) 1987-1993 The Regents of the University of California.
8 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
9 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * RCS: @(#) $Id: tclProc.c,v 1.44.2.6 2006/11/28 22:20:02 andreas_kupries Exp $
18 #include "tclCompile.h"
21 * Prototypes for static functions in this file
24 static void ProcBodyDup _ANSI_ARGS_((Tcl_Obj *srcPtr, Tcl_Obj *dupPtr));
25 static void ProcBodyFree _ANSI_ARGS_((Tcl_Obj *objPtr));
26 static int ProcBodySetFromAny _ANSI_ARGS_((Tcl_Interp *interp,
28 static void ProcBodyUpdateString _ANSI_ARGS_((Tcl_Obj *objPtr));
29 static int ProcCompileProc _ANSI_ARGS_((Tcl_Interp *interp,
30 Proc *procPtr, Tcl_Obj *bodyPtr, Namespace *nsPtr,
31 CONST char *description, CONST char *procName,
33 static int ProcessProcResultCode _ANSI_ARGS_((Tcl_Interp *interp,
34 char *procName, int nameLen, int returnCode));
35 static int TclCompileNoOp _ANSI_ARGS_((Tcl_Interp *interp,
36 Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
39 * The ProcBodyObjType type
42 Tcl_ObjType tclProcBodyType = {
43 "procbody", /* name for this type */
44 ProcBodyFree, /* FreeInternalRep procedure */
45 ProcBodyDup, /* DupInternalRep procedure */
46 ProcBodyUpdateString, /* UpdateString procedure */
47 ProcBodySetFromAny /* SetFromAny procedure */
51 *----------------------------------------------------------------------
55 * This object-based procedure is invoked to process the "proc" Tcl
56 * command. See the user documentation for details on what it does.
59 * A standard Tcl object result value.
62 * A new procedure gets created.
64 *----------------------------------------------------------------------
69 Tcl_ProcObjCmd(dummy, interp, objc, objv)
70 ClientData dummy; /* Not used. */
71 Tcl_Interp *interp; /* Current interpreter. */
72 int objc; /* Number of arguments. */
73 Tcl_Obj *CONST objv[]; /* Argument objects. */
75 register Interp *iPtr = (Interp *) interp;
78 CONST char *procName, *procArgs, *procBody;
79 Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
84 Tcl_WrongNumArgs(interp, 1, objv, "name args body");
89 * Determine the namespace where the procedure should reside. Unless
90 * the command name includes namespace qualifiers, this will be the
94 fullName = TclGetString(objv[1]);
95 TclGetNamespaceForQualName(interp, fullName, (Namespace *) NULL,
96 0, &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
99 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
100 "can't create procedure \"", fullName,
101 "\": unknown namespace", (char *) NULL);
104 if (procName == NULL) {
105 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
106 "can't create procedure \"", fullName,
107 "\": bad procedure name", (char *) NULL);
110 if ((nsPtr != iPtr->globalNsPtr)
111 && (procName != NULL) && (procName[0] == ':')) {
112 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
113 "can't create procedure \"", procName,
114 "\" in non-global namespace with name starting with \":\"",
120 * Create the data structure to represent the procedure.
122 if (TclCreateProc(interp, nsPtr, procName, objv[2], objv[3],
123 &procPtr) != TCL_OK) {
128 * Now create a command for the procedure. This will initially be in
129 * the current namespace unless the procedure's name included namespace
130 * qualifiers. To create the new command in the right namespace, we
131 * generate a fully qualified name for it.
134 Tcl_DStringInit(&ds);
135 if (nsPtr != iPtr->globalNsPtr) {
136 Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
137 Tcl_DStringAppend(&ds, "::", 2);
139 Tcl_DStringAppend(&ds, procName, -1);
141 Tcl_CreateCommand(interp, Tcl_DStringValue(&ds), TclProcInterpProc,
142 (ClientData) procPtr, TclProcDeleteProc);
143 cmd = Tcl_CreateObjCommand(interp, Tcl_DStringValue(&ds),
144 TclObjInterpProc, (ClientData) procPtr, TclProcDeleteProc);
146 Tcl_DStringFree(&ds);
148 * Now initialize the new procedure's cmdPtr field. This will be used
149 * later when the procedure is called to determine what namespace the
150 * procedure will run in. This will be different than the current
151 * namespace if the proc was renamed into a different namespace.
154 procPtr->cmdPtr = (Command *) cmd;
157 /* TIP #280 Remember the line the procedure body is starting on. In a
158 * Byte code context we ask the engine to provide us with the necessary
159 * information. This is for the initialization of the byte code compiler
160 * when the body is used for the first time.
163 if (iPtr->cmdFramePtr) {
164 CmdFrame context = *iPtr->cmdFramePtr;
166 if (context.type == TCL_LOCATION_BC) {
167 TclGetSrcInfoForPc (&context);
168 /* May get path in context */
169 } else if (context.type == TCL_LOCATION_SOURCE) {
170 /* context now holds another reference */
171 Tcl_IncrRefCount (context.data.eval.path);
174 /* type == TCL_LOCATION_PREBC implies that 'line' is NULL here! We
175 * cannot assume that 'line' is valid here, we have to check. If the
176 * outer context is an eval (bc, prebc, eval) we do not save any
177 * information. Counting relative to the beginning of the proc body is
178 * more sensible than counting relative to the outer eval block.
181 if ((context.type == TCL_LOCATION_SOURCE) &&
183 (context.nline >= 4) &&
184 (context.line [3] >= 0)) {
186 CmdFrame* cfPtr = (CmdFrame*) ckalloc (sizeof (CmdFrame));
189 cfPtr->type = context.type;
190 cfPtr->line = (int*) ckalloc (sizeof (int));
191 cfPtr->line [0] = context.line [3];
193 cfPtr->framePtr = NULL;
194 cfPtr->nextPtr = NULL;
196 if (context.type == TCL_LOCATION_SOURCE) {
197 cfPtr->data.eval.path = context.data.eval.path;
198 /* Transfer of reference. The reference going away (release of
199 * the context) is replaced by the reference in the
200 * constructed cmdframe */
202 cfPtr->type = TCL_LOCATION_EVAL;
203 cfPtr->data.eval.path = NULL;
206 cfPtr->cmd.str.cmd = NULL;
207 cfPtr->cmd.str.len = 0;
209 Tcl_SetHashValue (Tcl_CreateHashEntry (iPtr->linePBodyPtr,
210 (char*) procPtr, &new),
217 * Optimize for noop procs: if the body is not precompiled (like a TclPro
218 * procbody), and the argument list is just "args" and the body is empty,
219 * define a compileProc to compile a noop.
222 * - cannot be done for any argument list without having different
223 * compiled/not-compiled behaviour in the "wrong argument #" case,
224 * or making this code much more complicated. In any case, it doesn't
225 * seem to make a lot of sense to verify the number of arguments we
226 * are about to ignore ...
227 * - could be enhanced to handle also non-empty bodies that contain
228 * only comments; however, parsing the body will slow down the
229 * compilation of all procs whose argument list is just _args_ */
231 if (objv[3]->typePtr == &tclProcBodyType) {
235 procArgs = Tcl_GetString(objv[2]);
237 while (*procArgs == ' ') {
241 if ((procArgs[0] == 'a') && (strncmp(procArgs, "args", 4) == 0)) {
243 while(*procArgs != '\0') {
244 if (*procArgs != ' ') {
251 * The argument list is just "args"; check the body
254 procBody = Tcl_GetString(objv[3]);
255 while (*procBody != '\0') {
256 if (!isspace(UCHAR(*procBody))) {
263 * The body is just spaces: link the compileProc
266 ((Command *) cmd)->compileProc = TclCompileNoOp;
274 *----------------------------------------------------------------------
278 * Creates the data associated with a Tcl procedure definition.
279 * This procedure knows how to handle two types of body objects:
280 * strings and procbody. Strings are the traditional (and common) value
281 * for bodies, procbody are values created by extensions that have
282 * loaded a previously compiled script.
285 * Returns TCL_OK on success, along with a pointer to a Tcl
286 * procedure definition in procPtrPtr. This definition should
287 * be freed by calling TclCleanupProc() when it is no longer
288 * needed. Returns TCL_ERROR if anything goes wrong.
291 * If anything goes wrong, this procedure returns an error
292 * message in the interpreter.
294 *----------------------------------------------------------------------
297 TclCreateProc(interp, nsPtr, procName, argsPtr, bodyPtr, procPtrPtr)
298 Tcl_Interp *interp; /* interpreter containing proc */
299 Namespace *nsPtr; /* namespace containing this proc */
300 CONST char *procName; /* unqualified name of this proc */
301 Tcl_Obj *argsPtr; /* description of arguments */
302 Tcl_Obj *bodyPtr; /* command body */
303 Proc **procPtrPtr; /* returns: pointer to proc data */
305 Interp *iPtr = (Interp*)interp;
306 CONST char **argArray = NULL;
308 register Proc *procPtr;
309 int i, length, result, numArgs;
310 CONST char *args, *bytes, *p;
311 register CompiledLocal *localPtr = NULL;
315 if (bodyPtr->typePtr == &tclProcBodyType) {
317 * Because the body is a TclProProcBody, the actual body is already
318 * compiled, and it is not shared with anyone else, so it's OK not to
319 * unshare it (as a matter of fact, it is bad to unshare it, because
320 * there may be no source code).
322 * We don't create and initialize a Proc structure for the procedure;
323 * rather, we use what is in the body object. Note that
324 * we initialize its cmdPtr field below after we've created the command
325 * for the procedure. We increment the ref count of the Proc struct
326 * since the command (soon to be created) will be holding a reference
330 procPtr = (Proc *) bodyPtr->internalRep.otherValuePtr;
331 procPtr->iPtr = iPtr;
336 * If the procedure's body object is shared because its string value is
337 * identical to, e.g., the body of another procedure, we must create a
338 * private copy for this procedure to use. Such sharing of procedure
339 * bodies is rare but can cause problems. A procedure body is compiled
340 * in a context that includes the number of compiler-allocated "slots"
341 * for local variables. Each formal parameter is given a local variable
342 * slot (the "procPtr->numCompiledLocals = numArgs" assignment
343 * below). This means that the same code can not be shared by two
344 * procedures that have a different number of arguments, even if their
345 * bodies are identical. Note that we don't use Tcl_DuplicateObj since
346 * we would not want any bytecode internal representation.
349 if (Tcl_IsShared(bodyPtr)) {
350 bytes = Tcl_GetStringFromObj(bodyPtr, &length);
351 bodyPtr = Tcl_NewStringObj(bytes, length);
355 * Create and initialize a Proc structure for the procedure. Note that
356 * we initialize its cmdPtr field below after we've created the command
357 * for the procedure. We increment the ref count of the procedure's
358 * body object since there will be a reference to it in the Proc
362 Tcl_IncrRefCount(bodyPtr);
364 procPtr = (Proc *) ckalloc(sizeof(Proc));
365 procPtr->iPtr = iPtr;
366 procPtr->refCount = 1;
367 procPtr->bodyPtr = bodyPtr;
368 procPtr->numArgs = 0; /* actual argument count is set below. */
369 procPtr->numCompiledLocals = 0;
370 procPtr->firstLocalPtr = NULL;
371 procPtr->lastLocalPtr = NULL;
375 * Break up the argument list into argument specifiers, then process
376 * each argument specifier.
377 * If the body is precompiled, processing is limited to checking that
378 * the the parsed argument is consistent with the one stored in the
380 * THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULLS.
383 args = Tcl_GetStringFromObj(argsPtr, &length);
384 result = Tcl_SplitList(interp, args, &numArgs, &argArray);
385 if (result != TCL_OK) {
390 if (numArgs > procPtr->numArgs) {
391 char buf[64 + TCL_INTEGER_SPACE + TCL_INTEGER_SPACE];
392 sprintf(buf, "\": arg list contains %d entries, precompiled header expects %d",
393 numArgs, procPtr->numArgs);
394 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
395 "procedure \"", procName,
399 localPtr = procPtr->firstLocalPtr;
401 procPtr->numArgs = numArgs;
402 procPtr->numCompiledLocals = numArgs;
404 for (i = 0; i < numArgs; i++) {
405 int fieldCount, nameLength, valueLength;
406 CONST char **fieldValues;
409 * Now divide the specifier up into name and default.
412 result = Tcl_SplitList(interp, argArray[i], &fieldCount,
414 if (result != TCL_OK) {
417 if (fieldCount > 2) {
418 ckfree((char *) fieldValues);
419 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
420 "too many fields in argument specifier \"",
421 argArray[i], "\"", (char *) NULL);
424 if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
425 ckfree((char *) fieldValues);
426 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
427 "procedure \"", procName,
428 "\" has argument with no name", (char *) NULL);
432 nameLength = strlen(fieldValues[0]);
433 if (fieldCount == 2) {
434 valueLength = strlen(fieldValues[1]);
440 * Check that the formal parameter name is a scalar.
449 } while (*q != '\0');
451 if (*q == ')') { /* we have an array element */
452 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
453 "procedure \"", procName,
454 "\" has formal parameter \"", fieldValues[0],
455 "\" that is an array element",
457 ckfree((char *) fieldValues);
460 } else if ((*p == ':') && (*(p+1) == ':')) {
461 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
462 "procedure \"", procName,
463 "\" has formal parameter \"", fieldValues[0],
464 "\" that is not a simple name",
466 ckfree((char *) fieldValues);
474 * Compare the parsed argument with the stored one.
475 * For the flags, we and out VAR_UNDEFINED to support bridging
476 * precompiled <= 8.3 code in 8.4 where this is now used as an
477 * optimization indicator. Yes, this is a hack. -- hobbs
480 if ((localPtr->nameLength != nameLength)
481 || (strcmp(localPtr->name, fieldValues[0]))
482 || (localPtr->frameIndex != i)
483 || ((localPtr->flags & ~VAR_UNDEFINED)
484 != (VAR_SCALAR | VAR_ARGUMENT))
485 || ((localPtr->defValuePtr == NULL)
486 && (fieldCount == 2))
487 || ((localPtr->defValuePtr != NULL)
488 && (fieldCount != 2))) {
489 char buf[80 + TCL_INTEGER_SPACE];
490 sprintf(buf, "\": formal parameter %d is inconsistent with precompiled body",
492 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
493 "procedure \"", procName,
495 ckfree((char *) fieldValues);
500 * compare the default value if any
503 if (localPtr->defValuePtr != NULL) {
505 char *tmpPtr = Tcl_GetStringFromObj(localPtr->defValuePtr,
507 if ((valueLength != tmpLength)
508 || (strncmp(fieldValues[1], tmpPtr,
509 (size_t) tmpLength))) {
510 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
511 "procedure \"", procName,
512 "\": formal parameter \"",
514 "\" has default value inconsistent with precompiled body",
516 ckfree((char *) fieldValues);
521 localPtr = localPtr->nextPtr;
524 * Allocate an entry in the runtime procedure frame's array of
525 * local variables for the argument.
528 localPtr = (CompiledLocal *) ckalloc((unsigned)
529 (sizeof(CompiledLocal) - sizeof(localPtr->name)
531 if (procPtr->firstLocalPtr == NULL) {
532 procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
534 procPtr->lastLocalPtr->nextPtr = localPtr;
535 procPtr->lastLocalPtr = localPtr;
537 localPtr->nextPtr = NULL;
538 localPtr->nameLength = nameLength;
539 localPtr->frameIndex = i;
540 localPtr->flags = VAR_SCALAR | VAR_ARGUMENT;
541 localPtr->resolveInfo = NULL;
543 if (fieldCount == 2) {
544 localPtr->defValuePtr =
545 Tcl_NewStringObj(fieldValues[1], valueLength);
546 Tcl_IncrRefCount(localPtr->defValuePtr);
548 localPtr->defValuePtr = NULL;
550 strcpy(localPtr->name, fieldValues[0]);
553 ckfree((char *) fieldValues);
557 * Now initialize the new procedure's cmdPtr field. This will be used
558 * later when the procedure is called to determine what namespace the
559 * procedure will run in. This will be different than the current
560 * namespace if the proc was renamed into a different namespace.
563 *procPtrPtr = procPtr;
564 ckfree((char *) argArray);
571 Tcl_DecrRefCount(bodyPtr);
572 while (procPtr->firstLocalPtr != NULL) {
573 localPtr = procPtr->firstLocalPtr;
574 procPtr->firstLocalPtr = localPtr->nextPtr;
576 defPtr = localPtr->defValuePtr;
577 if (defPtr != NULL) {
578 Tcl_DecrRefCount(defPtr);
581 ckfree((char *) localPtr);
583 ckfree((char *) procPtr);
585 if (argArray != NULL) {
586 ckfree((char *) argArray);
592 *----------------------------------------------------------------------
596 * Given a description of a procedure frame, such as the first
597 * argument to an "uplevel" or "upvar" command, locate the
598 * call frame for the appropriate level of procedure.
601 * The return value is -1 if an error occurred in finding the frame
602 * (in this case an error message is left in the interp's result).
603 * 1 is returned if string was either a number or a number preceded
604 * by "#" and it specified a valid frame. 0 is returned if string
605 * isn't one of the two things above (in this case, the lookup
606 * acts as if string were "1"). The variable pointed to by
607 * framePtrPtr is filled in with the address of the desired frame
608 * (unless an error occurs, in which case it isn't modified).
613 *----------------------------------------------------------------------
617 TclGetFrame(interp, string, framePtrPtr)
618 Tcl_Interp *interp; /* Interpreter in which to find frame. */
619 CONST char *string; /* String describing frame. */
620 CallFrame **framePtrPtr; /* Store pointer to frame here (or NULL
621 * if global frame indicated). */
623 register Interp *iPtr = (Interp *) interp;
624 int curLevel, level, result;
628 * Parse string to figure out which level number to go to.
632 curLevel = (iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level;
633 if (*string == '#') {
634 if (Tcl_GetInt(interp, string+1, &level) != TCL_OK) {
639 Tcl_AppendResult(interp, "bad level \"", string, "\"",
643 } else if (isdigit(UCHAR(*string))) { /* INTL: digit */
644 if (Tcl_GetInt(interp, string, &level) != TCL_OK) {
647 level = curLevel - level;
649 level = curLevel - 1;
654 * Figure out which frame to use, and modify the interpreter so
655 * its variables come from that frame.
661 for (framePtr = iPtr->varFramePtr; framePtr != NULL;
662 framePtr = framePtr->callerVarPtr) {
663 if (framePtr->level == level) {
667 if (framePtr == NULL) {
671 *framePtrPtr = framePtr;
676 *----------------------------------------------------------------------
678 * Tcl_UplevelObjCmd --
680 * This object procedure is invoked to process the "uplevel" Tcl
681 * command. See the user documentation for details on what it does.
684 * A standard Tcl object result value.
687 * See the user documentation.
689 *----------------------------------------------------------------------
694 Tcl_UplevelObjCmd(dummy, interp, objc, objv)
695 ClientData dummy; /* Not used. */
696 Tcl_Interp *interp; /* Current interpreter. */
697 int objc; /* Number of arguments. */
698 Tcl_Obj *CONST objv[]; /* Argument objects. */
700 register Interp *iPtr = (Interp *) interp;
703 CallFrame *savedVarFramePtr, *framePtr;
707 Tcl_WrongNumArgs(interp, 1, objv, "?level? command ?arg ...?");
712 * Find the level to use for executing the command.
715 optLevel = TclGetString(objv[1]);
716 result = TclGetFrame(interp, optLevel, &framePtr);
727 * Modify the interpreter state to execute in the given frame.
730 savedVarFramePtr = iPtr->varFramePtr;
731 iPtr->varFramePtr = framePtr;
734 * Execute the residual arguments as a command.
738 result = Tcl_EvalObjEx(interp, objv[0], TCL_EVAL_DIRECT);
741 * More than one argument: concatenate them together with spaces
742 * between, then evaluate the result. Tcl_EvalObjEx will delete
743 * the object when it decrements its refcount after eval'ing it.
747 objPtr = Tcl_ConcatObj(objc, objv);
748 result = Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_DIRECT);
750 if (result == TCL_ERROR) {
751 char msg[32 + TCL_INTEGER_SPACE];
752 sprintf(msg, "\n (\"uplevel\" body line %d)", interp->errorLine);
753 Tcl_AddObjErrorInfo(interp, msg, -1);
757 * Restore the variable frame, and return.
760 iPtr->varFramePtr = savedVarFramePtr;
765 *----------------------------------------------------------------------
769 * Given the name of a procedure, return a pointer to the
770 * record describing the procedure. The procedure will be
771 * looked up using the usual rules: first in the current
772 * namespace and then in the global namespace.
775 * NULL is returned if the name doesn't correspond to any
776 * procedure. Otherwise, the return value is a pointer to
777 * the procedure's record. If the name is found but refers
778 * to an imported command that points to a "real" procedure
779 * defined in another namespace, a pointer to that "real"
780 * procedure's structure is returned.
785 *----------------------------------------------------------------------
789 TclFindProc(iPtr, procName)
790 Interp *iPtr; /* Interpreter in which to look. */
791 CONST char *procName; /* Name of desired procedure. */
797 cmd = Tcl_FindCommand((Tcl_Interp *) iPtr, procName,
798 (Tcl_Namespace *) NULL, /*flags*/ 0);
799 if (cmd == (Tcl_Command) NULL) {
802 cmdPtr = (Command *) cmd;
804 origCmd = TclGetOriginalCommand(cmd);
805 if (origCmd != NULL) {
806 cmdPtr = (Command *) origCmd;
808 if (cmdPtr->proc != TclProcInterpProc) {
811 return (Proc *) cmdPtr->clientData;
815 *----------------------------------------------------------------------
819 * Tells whether a command is a Tcl procedure or not.
822 * If the given command is actually a Tcl procedure, the
823 * return value is the address of the record describing
824 * the procedure. Otherwise the return value is 0.
829 *----------------------------------------------------------------------
834 Command *cmdPtr; /* Command to test. */
838 origCmd = TclGetOriginalCommand((Tcl_Command) cmdPtr);
839 if (origCmd != NULL) {
840 cmdPtr = (Command *) origCmd;
842 if (cmdPtr->proc == TclProcInterpProc) {
843 return (Proc *) cmdPtr->clientData;
849 *----------------------------------------------------------------------
851 * TclProcInterpProc --
853 * When a Tcl procedure gets invoked with an argc/argv array of
854 * strings, this routine gets invoked to interpret the procedure.
857 * A standard Tcl result value, usually TCL_OK.
860 * Depends on the commands in the procedure.
862 *----------------------------------------------------------------------
866 TclProcInterpProc(clientData, interp, argc, argv)
867 ClientData clientData; /* Record describing procedure to be
869 Tcl_Interp *interp; /* Interpreter in which procedure was
871 int argc; /* Count of number of arguments to this
873 register CONST char **argv; /* Argument values. */
875 register Tcl_Obj *objPtr;
880 * This procedure generates an objv array for object arguments that hold
881 * the argv strings. It starts out with stack-allocated space but uses
882 * dynamically-allocated storage if needed.
886 Tcl_Obj *(objStorage[NUM_ARGS]);
887 register Tcl_Obj **objv = objStorage;
890 * Create the object argument array "objv". Make sure objv is large
891 * enough to hold the objc arguments plus 1 extra for the zero
895 if ((argc + 1) > NUM_ARGS) {
897 ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
900 for (i = 0; i < argc; i++) {
901 objv[i] = Tcl_NewStringObj(argv[i], -1);
902 Tcl_IncrRefCount(objv[i]);
907 * Use TclObjInterpProc to actually interpret the procedure.
910 result = TclObjInterpProc(clientData, interp, argc, objv);
913 * Move the interpreter's object result to the string result,
914 * then reset the object result.
917 Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
921 * Decrement the ref counts on the objv elements since we are done
925 for (i = 0; i < argc; i++) {
927 TclDecrRefCount(objPtr);
931 * Free the objv array if malloc'ed storage was used.
934 if (objv != objStorage) {
935 ckfree((char *) objv);
942 *----------------------------------------------------------------------
944 * TclObjInterpProc --
946 * When a Tcl procedure gets invoked during bytecode evaluation, this
947 * object-based routine gets invoked to interpret the procedure.
950 * A standard Tcl object result value.
953 * Depends on the commands in the procedure.
955 *----------------------------------------------------------------------
959 TclObjInterpProc(clientData, interp, objc, objv)
960 ClientData clientData; /* Record describing procedure to be
962 register Tcl_Interp *interp; /* Interpreter in which procedure was
964 int objc; /* Count of number of arguments to this
966 Tcl_Obj *CONST objv[]; /* Argument value objects. */
968 Interp *iPtr = (Interp *) interp;
969 Proc *procPtr = (Proc *) clientData;
970 Namespace *nsPtr = procPtr->cmdPtr->nsPtr;
972 register CallFrame *framePtr = &frame;
973 register Var *varPtr;
974 register CompiledLocal *localPtr;
976 int nameLen, localCt, numArgs, argCt, i, result;
979 * This procedure generates an array "compiledLocals" that holds the
980 * storage for local variables. It starts out with stack-allocated space
981 * but uses dynamically-allocated storage if needed.
984 #define NUM_LOCALS 20
985 Var localStorage[NUM_LOCALS];
986 Var *compiledLocals = localStorage;
989 * Get the procedure's name.
992 procName = Tcl_GetStringFromObj(objv[0], &nameLen);
995 * If necessary, compile the procedure's body. The compiler will
996 * allocate frame slots for the procedure's non-argument local
997 * variables. Note that compiling the body might increase
998 * procPtr->numCompiledLocals if new local variables are found
1002 result = ProcCompileProc(interp, procPtr, procPtr->bodyPtr, nsPtr,
1003 "body of proc", procName, &procPtr);
1005 if (result != TCL_OK) {
1010 * Create the "compiledLocals" array. Make sure it is large enough to
1011 * hold all the procedure's compiled local variables, including its
1012 * formal parameters.
1015 localCt = procPtr->numCompiledLocals;
1016 if (localCt > NUM_LOCALS) {
1017 compiledLocals = (Var *) ckalloc((unsigned) localCt * sizeof(Var));
1021 * Set up and push a new call frame for the new procedure invocation.
1022 * This call frame will execute in the proc's namespace, which might
1023 * be different than the current namespace. The proc's namespace is
1024 * that of its command, which can change if the command is renamed
1025 * from one namespace to another.
1028 result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
1029 (Tcl_Namespace *) nsPtr, /*isProcCallFrame*/ 1);
1031 if (result != TCL_OK) {
1035 framePtr->objc = objc;
1036 framePtr->objv = objv; /* ref counts for args are incremented below */
1039 * Initialize and resolve compiled variable references.
1042 framePtr->procPtr = procPtr;
1043 framePtr->numCompiledLocals = localCt;
1044 framePtr->compiledLocals = compiledLocals;
1046 TclInitCompiledLocals(interp, framePtr, nsPtr);
1049 * Match and assign the call's actual parameters to the procedure's
1050 * formal arguments. The formal arguments are described by the first
1051 * numArgs entries in both the Proc structure's local variable list and
1052 * the call frame's local variable array.
1055 numArgs = procPtr->numArgs;
1056 varPtr = framePtr->compiledLocals;
1057 localPtr = procPtr->firstLocalPtr;
1059 for (i = 1, argCt -= 1; i <= numArgs; i++, argCt--) {
1060 if (!TclIsVarArgument(localPtr)) {
1061 panic("TclObjInterpProc: local variable %s is not argument but should be",
1065 if (TclIsVarTemporary(localPtr)) {
1066 panic("TclObjInterpProc: local variable %d is temporary but should be an argument", i);
1071 * Handle the special case of the last formal being "args". When
1072 * it occurs, assign it a list consisting of all the remaining
1076 if ((i == numArgs) && ((localPtr->name[0] == 'a')
1077 && (strcmp(localPtr->name, "args") == 0))) {
1078 Tcl_Obj *listPtr = Tcl_NewListObj(argCt, &(objv[i]));
1079 varPtr->value.objPtr = listPtr;
1080 Tcl_IncrRefCount(listPtr); /* local var is a reference */
1081 TclClearVarUndefined(varPtr);
1083 break; /* done processing args */
1084 } else if (argCt > 0) {
1085 Tcl_Obj *objPtr = objv[i];
1086 varPtr->value.objPtr = objPtr;
1087 TclClearVarUndefined(varPtr);
1088 Tcl_IncrRefCount(objPtr); /* since the local variable now has
1089 * another reference to object. */
1090 } else if (localPtr->defValuePtr != NULL) {
1091 Tcl_Obj *objPtr = localPtr->defValuePtr;
1092 varPtr->value.objPtr = objPtr;
1093 TclClearVarUndefined(varPtr);
1094 Tcl_IncrRefCount(objPtr); /* since the local variable now has
1095 * another reference to object. */
1100 localPtr = localPtr->nextPtr;
1108 * Build up equivalent to Tcl_WrongNumArgs message for proc
1111 Tcl_ResetResult(interp);
1112 objResult = Tcl_GetObjResult(interp);
1113 Tcl_AppendToObj(objResult, "wrong # args: should be \"", -1);
1116 * Quote the proc name if it contains spaces (Bug 942757).
1119 len = Tcl_ScanCountedElement(procName, nameLen, &flags);
1120 if (len != nameLen) {
1121 char *procName1 = ckalloc((unsigned) len);
1122 len = Tcl_ConvertCountedElement(procName, nameLen, procName1, flags);
1123 Tcl_AppendToObj(objResult, procName1, len);
1126 Tcl_AppendToObj(objResult, procName, len);
1129 localPtr = procPtr->firstLocalPtr;
1130 for (i = 1; i <= numArgs; i++) {
1131 if (localPtr->defValuePtr != NULL) {
1132 Tcl_AppendStringsToObj(objResult,
1133 " ?", localPtr->name, "?", (char *) NULL);
1135 Tcl_AppendStringsToObj(objResult,
1136 " ", localPtr->name, (char *) NULL);
1138 localPtr = localPtr->nextPtr;
1140 Tcl_AppendStringsToObj(objResult, "\"", (char *) NULL);
1147 * Invoke the commands in the procedure's body.
1150 #ifdef TCL_COMPILE_DEBUG
1151 if (tclTraceExec >= 1) {
1152 fprintf(stdout, "Calling proc ");
1153 for (i = 0; i < objc; i++) {
1154 TclPrintObject(stdout, objv[i], 15);
1155 fprintf(stdout, " ");
1157 fprintf(stdout, "\n");
1160 #endif /*TCL_COMPILE_DEBUG*/
1162 iPtr->returnCode = TCL_OK;
1163 procPtr->refCount++;
1165 result = TclCompEvalObj(interp, procPtr->bodyPtr);
1167 /* TIP #280: No need to set the invoking context here. The body has
1168 * already been compiled, so the part of CompEvalObj using it is bypassed.
1171 result = TclCompEvalObj(interp, procPtr->bodyPtr, NULL, 0);
1173 procPtr->refCount--;
1174 if (procPtr->refCount <= 0) {
1175 TclProcCleanupProc(procPtr);
1178 if (result != TCL_OK) {
1179 result = ProcessProcResultCode(interp, procName, nameLen, result);
1183 * Pop and free the call frame for this procedure invocation, then
1184 * free the compiledLocals array if malloc'ed storage was used.
1188 Tcl_PopCallFrame(interp);
1189 if (compiledLocals != localStorage) {
1190 ckfree((char *) compiledLocals);
1197 *----------------------------------------------------------------------
1199 * TclProcCompileProc --
1201 * Called just before a procedure is executed to compile the
1202 * body to byte codes. If the type of the body is not
1203 * "byte code" or if the compile conditions have changed
1204 * (namespace context, epoch counters, etc.) then the body
1205 * is recompiled. Otherwise, this procedure does nothing.
1211 * May change the internal representation of the body object
1214 *----------------------------------------------------------------------
1218 TclProcCompileProc(interp, procPtr, bodyPtr, nsPtr, description, procName)
1219 Tcl_Interp *interp; /* Interpreter containing procedure. */
1220 Proc *procPtr; /* Data associated with procedure. */
1221 Tcl_Obj *bodyPtr; /* Body of proc. (Usually procPtr->bodyPtr,
1222 * but could be any code fragment compiled
1223 * in the context of this procedure.) */
1224 Namespace *nsPtr; /* Namespace containing procedure. */
1225 CONST char *description; /* string describing this body of code. */
1226 CONST char *procName; /* Name of this procedure. */
1228 return ProcCompileProc(interp, procPtr, bodyPtr, nsPtr,
1229 description, procName, NULL);
1233 ProcCompileProc(interp, procPtr, bodyPtr, nsPtr, description,
1234 procName, procPtrPtr)
1235 Tcl_Interp *interp; /* Interpreter containing procedure. */
1236 Proc *procPtr; /* Data associated with procedure. */
1237 Tcl_Obj *bodyPtr; /* Body of proc. (Usually procPtr->bodyPtr,
1238 * but could be any code fragment compiled
1239 * in the context of this procedure.) */
1240 Namespace *nsPtr; /* Namespace containing procedure. */
1241 CONST char *description; /* string describing this body of code. */
1242 CONST char *procName; /* Name of this procedure. */
1243 Proc **procPtrPtr; /* points to storage where a replacement
1244 * (Proc *) value may be written, when
1247 Interp *iPtr = (Interp*)interp;
1249 Tcl_CallFrame frame;
1251 ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;
1252 CompiledLocal *localPtr;
1255 * If necessary, compile the procedure's body. The compiler will
1256 * allocate frame slots for the procedure's non-argument local
1257 * variables. If the ByteCode already exists, make sure it hasn't been
1258 * invalidated by someone redefining a core command (this might make the
1259 * compiled code wrong). Also, if the code was compiled in/for a
1260 * different interpreter, we recompile it. Note that compiling the body
1261 * might increase procPtr->numCompiledLocals if new local variables are
1262 * found while compiling.
1264 * Precompiled procedure bodies, however, are immutable and therefore
1265 * they are not recompiled, even if things have changed.
1268 if (bodyPtr->typePtr == &tclByteCodeType) {
1269 if (((Interp *) *codePtr->interpHandle != iPtr)
1270 || (codePtr->compileEpoch != iPtr->compileEpoch)
1271 || (codePtr->nsPtr != nsPtr)) {
1272 if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
1273 if ((Interp *) *codePtr->interpHandle != iPtr) {
1274 Tcl_AppendResult(interp,
1275 "a precompiled script jumped interps", NULL);
1278 codePtr->compileEpoch = iPtr->compileEpoch;
1279 codePtr->nsPtr = nsPtr;
1281 (*tclByteCodeType.freeIntRepProc)(bodyPtr);
1282 bodyPtr->typePtr = (Tcl_ObjType *) NULL;
1286 if (bodyPtr->typePtr != &tclByteCodeType) {
1290 #ifdef TCL_COMPILE_DEBUG
1291 if (tclTraceCompile >= 1) {
1293 * Display a line summarizing the top level command we
1294 * are about to compile.
1297 numChars = strlen(procName);
1299 if (numChars > 50) {
1303 fprintf(stdout, "Compiling %s \"%.*s%s\"\n",
1304 description, numChars, procName, ellipsis);
1309 * Plug the current procPtr into the interpreter and coerce
1310 * the code body to byte codes. The interpreter needs to
1311 * know which proc it's compiling so that it can access its
1312 * list of compiled locals.
1314 * TRICKY NOTE: Be careful to push a call frame with the
1315 * proper namespace context, so that the byte codes are
1316 * compiled in the appropriate class context.
1319 saveProcPtr = iPtr->compiledProcPtr;
1321 if (procPtrPtr != NULL && procPtr->refCount > 1) {
1324 Proc *new = (Proc *) ckalloc(sizeof(Proc));
1326 new->iPtr = procPtr->iPtr;
1328 new->cmdPtr = procPtr->cmdPtr;
1329 token = (Tcl_Command) new->cmdPtr;
1330 new->bodyPtr = Tcl_DuplicateObj(bodyPtr);
1331 bodyPtr = new->bodyPtr;
1332 Tcl_IncrRefCount(bodyPtr);
1333 new->numArgs = procPtr->numArgs;
1335 new->numCompiledLocals = new->numArgs;
1336 new->firstLocalPtr = NULL;
1337 new->lastLocalPtr = NULL;
1338 localPtr = procPtr->firstLocalPtr;
1339 for (i = 0; i < new->numArgs; i++, localPtr = localPtr->nextPtr) {
1340 CompiledLocal *copy = (CompiledLocal *) ckalloc((unsigned)
1341 (sizeof(CompiledLocal) -sizeof(localPtr->name)
1342 + localPtr->nameLength + 1));
1343 if (new->firstLocalPtr == NULL) {
1344 new->firstLocalPtr = new->lastLocalPtr = copy;
1346 new->lastLocalPtr->nextPtr = copy;
1347 new->lastLocalPtr = copy;
1349 copy->nextPtr = NULL;
1350 copy->nameLength = localPtr->nameLength;
1351 copy->frameIndex = localPtr->frameIndex;
1352 copy->flags = localPtr->flags;
1353 copy->defValuePtr = localPtr->defValuePtr;
1354 if (copy->defValuePtr) {
1355 Tcl_IncrRefCount(copy->defValuePtr);
1357 copy->resolveInfo = localPtr->resolveInfo;
1358 strcpy(copy->name, localPtr->name);
1362 /* Reset the ClientData */
1363 Tcl_GetCommandInfoFromToken(token, &info);
1364 if (info.objClientData == (ClientData) procPtr) {
1365 info.objClientData = (ClientData) new;
1367 if (info.clientData == (ClientData) procPtr) {
1368 info.clientData = (ClientData) new;
1370 if (info.deleteData == (ClientData) procPtr) {
1371 info.deleteData = (ClientData) new;
1373 Tcl_SetCommandInfoFromToken(token, &info);
1375 procPtr->refCount--;
1376 *procPtrPtr = procPtr = new;
1378 iPtr->compiledProcPtr = procPtr;
1380 result = Tcl_PushCallFrame(interp, &frame,
1381 (Tcl_Namespace*)nsPtr, /* isProcCallFrame */ 0);
1383 if (result == TCL_OK) {
1385 /* TIP #280. We get the invoking context from the cmdFrame
1386 * which was saved by 'Tcl_ProcObjCmd' (using linePBodyPtr).
1389 Tcl_HashEntry* hePtr = Tcl_FindHashEntry (iPtr->linePBodyPtr, (char *) procPtr);
1391 /* Constructed saved frame has body as word 0. See Tcl_ProcObjCmd.
1393 iPtr->invokeWord = 0;
1394 iPtr->invokeCmdFramePtr = (hePtr
1395 ? (CmdFrame*) Tcl_GetHashValue (hePtr)
1398 result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);
1400 iPtr->invokeCmdFramePtr = NULL;
1402 Tcl_PopCallFrame(interp);
1405 iPtr->compiledProcPtr = saveProcPtr;
1407 if (result != TCL_OK) {
1408 if (result == TCL_ERROR) {
1409 char buf[100 + TCL_INTEGER_SPACE];
1411 numChars = strlen(procName);
1413 if (numChars > 50) {
1417 while ( (procName[numChars] & 0xC0) == 0x80 ) {
1419 * Back up truncation point so that we don't truncate
1420 * in the middle of a multi-byte character (in UTF-8)
1425 sprintf(buf, "\n (compiling %s \"%.*s%s\", line %d)",
1426 description, numChars, procName, ellipsis,
1428 Tcl_AddObjErrorInfo(interp, buf, -1);
1432 } else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
1435 * The resolver epoch has changed, but we only need to invalidate
1436 * the resolver cache.
1439 for (localPtr = procPtr->firstLocalPtr; localPtr != NULL;
1440 localPtr = localPtr->nextPtr) {
1441 localPtr->flags &= ~(VAR_RESOLVED);
1442 if (localPtr->resolveInfo) {
1443 if (localPtr->resolveInfo->deleteProc) {
1444 localPtr->resolveInfo->deleteProc(localPtr->resolveInfo);
1446 ckfree((char*)localPtr->resolveInfo);
1448 localPtr->resolveInfo = NULL;
1456 *----------------------------------------------------------------------
1458 * ProcessProcResultCode --
1460 * Procedure called by TclObjInterpProc to process a return code other
1461 * than TCL_OK returned by a Tcl procedure.
1464 * Depending on the argument return code, the result returned is
1465 * another return code and the interpreter's result is set to a value
1466 * to supplement that return code.
1469 * If the result returned is TCL_ERROR, traceback information about
1470 * the procedure just executed is appended to the interpreter's
1471 * "errorInfo" variable.
1473 *----------------------------------------------------------------------
1477 ProcessProcResultCode(interp, procName, nameLen, returnCode)
1478 Tcl_Interp *interp; /* The interpreter in which the procedure
1479 * was called and returned returnCode. */
1480 char *procName; /* Name of the procedure. Used for error
1481 * messages and trace information. */
1482 int nameLen; /* Number of bytes in procedure's name. */
1483 int returnCode; /* The unexpected result code. */
1485 Interp *iPtr = (Interp *) interp;
1486 char msg[100 + TCL_INTEGER_SPACE];
1487 char *ellipsis = "";
1489 if (returnCode == TCL_OK) {
1492 if ((returnCode > TCL_CONTINUE) || (returnCode < TCL_OK)) {
1495 if (returnCode == TCL_RETURN) {
1496 return TclUpdateReturnInfo(iPtr);
1498 if (returnCode != TCL_ERROR) {
1499 Tcl_ResetResult(interp);
1500 Tcl_AppendToObj(Tcl_GetObjResult(interp), ((returnCode == TCL_BREAK)
1501 ? "invoked \"break\" outside of a loop"
1502 : "invoked \"continue\" outside of a loop"), -1);
1508 while ( (procName[nameLen] & 0xC0) == 0x80 ) {
1510 * Back up truncation point so that we don't truncate in the
1511 * middle of a multi-byte character (in UTF-8)
1516 sprintf(msg, "\n (procedure \"%.*s%s\" line %d)", nameLen, procName,
1517 ellipsis, iPtr->errorLine);
1518 Tcl_AddObjErrorInfo(interp, msg, -1);
1523 *----------------------------------------------------------------------
1525 * TclProcDeleteProc --
1527 * This procedure is invoked just before a command procedure is
1528 * removed from an interpreter. Its job is to release all the
1529 * resources allocated to the procedure.
1535 * Memory gets freed, unless the procedure is actively being
1536 * executed. In this case the cleanup is delayed until the
1537 * last call to the current procedure completes.
1539 *----------------------------------------------------------------------
1543 TclProcDeleteProc(clientData)
1544 ClientData clientData; /* Procedure to be deleted. */
1546 Proc *procPtr = (Proc *) clientData;
1548 procPtr->refCount--;
1549 if (procPtr->refCount <= 0) {
1550 TclProcCleanupProc(procPtr);
1555 *----------------------------------------------------------------------
1557 * TclProcCleanupProc --
1559 * This procedure does all the real work of freeing up a Proc
1560 * structure. It's called only when the structure's reference
1561 * count becomes zero.
1567 * Memory gets freed.
1569 *----------------------------------------------------------------------
1573 TclProcCleanupProc(procPtr)
1574 register Proc *procPtr; /* Procedure to be deleted. */
1576 register CompiledLocal *localPtr;
1577 Tcl_Obj *bodyPtr = procPtr->bodyPtr;
1579 Tcl_ResolvedVarInfo *resVarInfo;
1581 Tcl_HashEntry* hePtr = NULL;
1582 CmdFrame* cfPtr = NULL;
1583 Interp* iPtr = procPtr->iPtr;
1586 if (bodyPtr != NULL) {
1587 Tcl_DecrRefCount(bodyPtr);
1589 for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; ) {
1590 CompiledLocal *nextPtr = localPtr->nextPtr;
1592 resVarInfo = localPtr->resolveInfo;
1594 if (resVarInfo->deleteProc) {
1595 (*resVarInfo->deleteProc)(resVarInfo);
1597 ckfree((char *) resVarInfo);
1601 if (localPtr->defValuePtr != NULL) {
1602 defPtr = localPtr->defValuePtr;
1603 Tcl_DecrRefCount(defPtr);
1605 ckfree((char *) localPtr);
1608 ckfree((char *) procPtr);
1611 /* TIP #280. Release the location data associated with this Proc
1612 * structure, if any. The interpreter may not exist (For example for
1613 * procbody structurues created by tbcload.
1618 hePtr = Tcl_FindHashEntry (iPtr->linePBodyPtr, (char *) procPtr);
1621 cfPtr = (CmdFrame*) Tcl_GetHashValue (hePtr);
1623 if (cfPtr->type == TCL_LOCATION_SOURCE) {
1624 Tcl_DecrRefCount (cfPtr->data.eval.path);
1625 cfPtr->data.eval.path = NULL;
1627 ckfree ((char*) cfPtr->line); cfPtr->line = NULL;
1628 ckfree ((char*) cfPtr);
1629 Tcl_DeleteHashEntry (hePtr);
1634 *----------------------------------------------------------------------
1636 * TclUpdateReturnInfo --
1638 * This procedure is called when procedures return, and at other
1639 * points where the TCL_RETURN code is used. It examines fields
1640 * such as iPtr->returnCode and iPtr->errorCode and modifies
1641 * the real return status accordingly.
1644 * The return value is the true completion code to use for
1645 * the procedure, instead of TCL_RETURN.
1648 * The errorInfo and errorCode variables may get modified.
1650 *----------------------------------------------------------------------
1654 TclUpdateReturnInfo(iPtr)
1655 Interp *iPtr; /* Interpreter for which TCL_RETURN
1656 * exception is being processed. */
1662 code = iPtr->returnCode;
1663 iPtr->returnCode = TCL_OK;
1664 if (code == TCL_ERROR) {
1665 errorCode = ((iPtr->errorCode != NULL) ? iPtr->errorCode : "NONE");
1666 objPtr = Tcl_NewStringObj(errorCode, -1);
1667 Tcl_IncrRefCount(objPtr);
1668 Tcl_ObjSetVar2((Tcl_Interp *) iPtr, iPtr->execEnvPtr->errorCode,
1669 NULL, objPtr, TCL_GLOBAL_ONLY);
1670 Tcl_DecrRefCount(objPtr);
1671 iPtr->flags |= ERROR_CODE_SET;
1672 if (iPtr->errorInfo != NULL) {
1673 objPtr = Tcl_NewStringObj(iPtr->errorInfo, -1);
1674 Tcl_IncrRefCount(objPtr);
1675 Tcl_ObjSetVar2((Tcl_Interp *) iPtr, iPtr->execEnvPtr->errorInfo,
1676 NULL, objPtr, TCL_GLOBAL_ONLY);
1677 Tcl_DecrRefCount(objPtr);
1678 iPtr->flags |= ERR_IN_PROGRESS;
1685 *----------------------------------------------------------------------
1687 * TclGetInterpProc --
1689 * Returns a pointer to the TclProcInterpProc procedure; this is different
1690 * from the value obtained from the TclProcInterpProc reference on systems
1691 * like Windows where import and export versions of a procedure exported
1695 * Returns the internal address of the TclProcInterpProc procedure.
1700 *----------------------------------------------------------------------
1706 return (TclCmdProcType) TclProcInterpProc;
1710 *----------------------------------------------------------------------
1712 * TclGetObjInterpProc --
1714 * Returns a pointer to the TclObjInterpProc procedure; this is different
1715 * from the value obtained from the TclObjInterpProc reference on systems
1716 * like Windows where import and export versions of a procedure exported
1720 * Returns the internal address of the TclObjInterpProc procedure.
1725 *----------------------------------------------------------------------
1729 TclGetObjInterpProc()
1731 return (TclObjCmdProcType) TclObjInterpProc;
1735 *----------------------------------------------------------------------
1737 * TclNewProcBodyObj --
1739 * Creates a new object, of type "procbody", whose internal
1740 * representation is the given Proc struct.
1741 * The newly created object's reference count is 0.
1744 * Returns a pointer to a newly allocated Tcl_Obj, 0 on error.
1747 * The reference count in the ByteCode attached to the Proc is bumped up
1748 * by one, since the internal rep stores a pointer to it.
1750 *----------------------------------------------------------------------
1754 TclNewProcBodyObj(procPtr)
1755 Proc *procPtr; /* the Proc struct to store as the internal
1756 * representation. */
1761 return (Tcl_Obj *) NULL;
1764 objPtr = Tcl_NewStringObj("", 0);
1767 objPtr->typePtr = &tclProcBodyType;
1768 objPtr->internalRep.otherValuePtr = (VOID *) procPtr;
1770 procPtr->refCount++;
1777 *----------------------------------------------------------------------
1781 * Tcl_ObjType's Dup function for the proc body object.
1782 * Bumps the reference count on the Proc stored in the internal
1789 * Sets up the object in dupPtr to be a duplicate of the one in srcPtr.
1791 *----------------------------------------------------------------------
1794 static void ProcBodyDup(srcPtr, dupPtr)
1795 Tcl_Obj *srcPtr; /* object to copy */
1796 Tcl_Obj *dupPtr; /* target object for the duplication */
1798 Proc *procPtr = (Proc *) srcPtr->internalRep.otherValuePtr;
1800 dupPtr->typePtr = &tclProcBodyType;
1801 dupPtr->internalRep.otherValuePtr = (VOID *) procPtr;
1802 procPtr->refCount++;
1806 *----------------------------------------------------------------------
1810 * Tcl_ObjType's Free function for the proc body object.
1811 * The reference count on its Proc struct is decreased by 1; if the count
1812 * reaches 0, the proc is freed.
1818 * If the reference count on the Proc struct reaches 0, the struct is freed.
1820 *----------------------------------------------------------------------
1824 ProcBodyFree(objPtr)
1825 Tcl_Obj *objPtr; /* the object to clean up */
1827 Proc *procPtr = (Proc *) objPtr->internalRep.otherValuePtr;
1828 procPtr->refCount--;
1829 if (procPtr->refCount <= 0) {
1830 TclProcCleanupProc(procPtr);
1835 *----------------------------------------------------------------------
1837 * ProcBodySetFromAny --
1839 * Tcl_ObjType's SetFromAny function for the proc body object.
1843 * Theoretically returns a TCL result code.
1846 * Calls panic, since we can't set the value of the object from a string
1847 * representation (or any other internal ones).
1849 *----------------------------------------------------------------------
1853 ProcBodySetFromAny(interp, objPtr)
1854 Tcl_Interp *interp; /* current interpreter */
1855 Tcl_Obj *objPtr; /* object pointer */
1857 panic("called ProcBodySetFromAny");
1860 * this to keep compilers happy.
1867 *----------------------------------------------------------------------
1869 * ProcBodyUpdateString --
1871 * Tcl_ObjType's UpdateString function for the proc body object.
1878 * Calls panic, since we this type has no string representation.
1880 *----------------------------------------------------------------------
1884 ProcBodyUpdateString(objPtr)
1885 Tcl_Obj *objPtr; /* the object to update */
1887 panic("called ProcBodyUpdateString");
1892 *----------------------------------------------------------------------
1896 * Procedure called to compile noOp's
1899 * The return value is TCL_OK, indicating successful compilation.
1902 * Instructions are added to envPtr to execute a noOp at runtime.
1904 *----------------------------------------------------------------------
1908 TclCompileNoOp(interp, parsePtr, envPtr)
1909 Tcl_Interp *interp; /* Used for error reporting. */
1910 Tcl_Parse *parsePtr; /* Points to a parse structure for the
1911 * command created by Tcl_ParseCommand. */
1912 CompileEnv *envPtr; /* Holds resulting instructions. */
1914 Tcl_Token *tokenPtr;
1916 int savedStackDepth = envPtr->currStackDepth;
1918 tokenPtr = parsePtr->tokenPtr;
1919 for(i = 1; i < parsePtr->numWords; i++) {
1920 tokenPtr = tokenPtr + tokenPtr->numComponents + 1;
1921 envPtr->currStackDepth = savedStackDepth;
1923 if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
1924 code = TclCompileTokens(interp, tokenPtr+1,
1925 tokenPtr->numComponents, envPtr);
1926 if (code != TCL_OK) {
1929 TclEmitOpcode(INST_POP, envPtr);
1932 envPtr->currStackDepth = savedStackDepth;
1933 TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0), envPtr);