summaryrefslogtreecommitdiffstats
path: root/generic/tclProc.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclProc.c')
-rw-r--r--generic/tclProc.c275
1 files changed, 64 insertions, 211 deletions
diff --git a/generic/tclProc.c b/generic/tclProc.c
index 8577470..6429488 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -11,12 +11,11 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclProc.c,v 1.94 2006/10/20 14:04:01 dkf Exp $
+ * RCS: @(#) $Id: tclProc.c,v 1.95 2006/10/20 15:16:47 dkf Exp $
*/
#include "tclInt.h"
#include "tclCompile.h"
-#include "tclOO.h"
/*
* Prototypes for static functions in this file
@@ -34,8 +33,7 @@ static int ObjInterpProcEx(ClientData clientData,
static void ProcBodyDup(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
static void ProcBodyFree(Tcl_Obj *objPtr);
static int ProcessProcResultCode(Tcl_Interp *interp,
- Tcl_Obj *procNameObj, int returnCode,
- int isMethod);
+ char *procName, int nameLen, int returnCode);
static int SetLambdaFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int ProcCompileProc (Tcl_Interp *interp, Proc *procPtr,
Tcl_Obj *bodyPtr, Namespace *nsPtr,
@@ -111,12 +109,12 @@ Tcl_ProcObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register Interp *iPtr = (Interp *) interp;
Proc *procPtr;
char *fullName;
- const char *procName, *procArgs, *procBody;
+ CONST char *procName, *procArgs, *procBody;
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
Tcl_Command cmd;
Tcl_DString ds;
@@ -280,17 +278,17 @@ int
TclCreateProc(
Tcl_Interp *interp, /* interpreter containing proc */
Namespace *nsPtr, /* namespace containing this proc */
- const char *procName, /* unqualified name of this proc */
+ CONST char *procName, /* unqualified name of this proc */
Tcl_Obj *argsPtr, /* description of arguments */
Tcl_Obj *bodyPtr, /* command body */
Proc **procPtrPtr) /* returns: pointer to proc data */
{
Interp *iPtr = (Interp*)interp;
- const char **argArray = NULL;
+ CONST char **argArray = NULL;
register Proc *procPtr;
int i, length, result, numArgs;
- const char *args, *bytes, *p;
+ CONST char *args, *bytes, *p;
register CompiledLocal *localPtr = NULL;
Tcl_Obj *defPtr;
int precompiled = 0;
@@ -384,7 +382,7 @@ TclCreateProc(
for (i = 0; i < numArgs; i++) {
int fieldCount, nameLength, valueLength;
- const char **fieldValues;
+ CONST char **fieldValues;
/*
* Now divide the specifier up into name and default.
@@ -422,7 +420,7 @@ TclCreateProc(
p = fieldValues[0];
while (*p != '\0') {
if (*p == '(') {
- const char *q = p;
+ CONST char *q = p;
do {
q++;
} while (*q != '\0');
@@ -593,7 +591,7 @@ TclCreateProc(
int
TclGetFrame(
Tcl_Interp *interp, /* Interpreter in which to find frame. */
- const char *name, /* String describing frame. */
+ CONST char *name, /* String describing frame. */
CallFrame **framePtrPtr) /* Store pointer to frame here (or NULL if
* global frame indicated). */
{
@@ -682,7 +680,7 @@ TclObjGetFrame(
register Interp *iPtr = (Interp *) interp;
int curLevel, level, result;
CallFrame *framePtr;
- const char *name = TclGetString(objPtr);
+ CONST char *name = TclGetString(objPtr);
/*
* Parse object to figure out which level number to go to.
@@ -800,7 +798,7 @@ Tcl_UplevelObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register Interp *iPtr = (Interp *) interp;
int result;
@@ -890,7 +888,7 @@ Tcl_UplevelObjCmd(
Proc *
TclFindProc(
Interp *iPtr, /* Interpreter in which to look. */
- const char *procName) /* Name of desired procedure. */
+ CONST char *procName) /* Name of desired procedure. */
{
Tcl_Command cmd;
Tcl_Command origCmd;
@@ -1120,7 +1118,7 @@ TclInitCompiledLocals(
/*
*----------------------------------------------------------------------
*
- * TclObjInterpProc, ObjInterpProcEx --
+ * TclObjInterpProc --
*
* When a Tcl procedure gets invoked during bytecode evaluation, this
* object-based routine gets invoked to interpret the procedure.
@@ -1142,8 +1140,9 @@ TclObjInterpProc(
* invoked. */
int objc, /* Count of number of arguments to this
* procedure. */
- Tcl_Obj *const objv[]) /* Argument value objects. */
+ Tcl_Obj *CONST objv[]) /* Argument value objects. */
{
+
return ObjInterpProcEx(clientData, interp, objc, objv, /*skip*/ 1);
}
@@ -1155,14 +1154,25 @@ ObjInterpProcEx(
* invoked. */
int objc, /* Count of number of arguments to this
* procedure. */
- Tcl_Obj *const objv[], /* Argument value objects. */
+ Tcl_Obj *CONST objv[], /* Argument value objects. */
int skip) /* Number of initial arguments to be skipped,
- * i.e., words in the "command name" */
+ * ie, words in the "command name" */
{
Proc *procPtr = (Proc *) clientData;
Namespace *nsPtr = procPtr->cmdPtr->nsPtr;
CallFrame *framePtr, **framePtrPtr;
- int result;
+ register Var *varPtr;
+ register CompiledLocal *localPtr;
+ char *procName;
+ int nameLen, localCt, numArgs, argCt, i, imax, result;
+ Var *compiledLocals;
+ Tcl_Obj *CONST *argObjs;
+
+ /*
+ * Get the procedure's name.
+ */
+
+ procName = Tcl_GetStringFromObj(objv[0], &nameLen);
/*
* If necessary, compile the procedure's body. The compiler will allocate
@@ -1172,12 +1182,13 @@ ObjInterpProcEx(
*/
result = ProcCompileProc(interp, procPtr, procPtr->bodyPtr, nsPtr,
- "body of proc", TclGetString(objv[0]), &procPtr);
+ "body of proc", procName, &procPtr);
if (result != TCL_OK) {
return result;
}
+
/*
* Set up and push a new call frame for the new procedure invocation.
* This call frame will execute in the proc's namespace, which might be
@@ -1194,50 +1205,11 @@ ObjInterpProcEx(
return result;
}
+
framePtr->objc = objc;
framePtr->objv = objv; /* ref counts for args are incremented below */
framePtr->procPtr = procPtr;
- return TclObjInterpProcCore(interp, framePtr, objv[0], skip);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclObjInterpProcCore --
- *
- * When a Tcl procedure, procedure-like method or lambda term gets
- * invoked during bytecode evaluation, this object-based routine gets
- * invoked to interpret the body.
- *
- * Results:
- * A standard Tcl object result value.
- *
- * Side effects:
- * Depends on the commands in the procedure body.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclObjInterpProcCore(
- register Tcl_Interp *interp,/* Interpreter in which procedure was
- * invoked. */
- CallFrame *framePtr, /* The context to execute. The procPtr field
- * must be non-NULL. */
- Tcl_Obj *procNameObj, /* Procedure name for error reporting. */
- int skip) /* Number of initial arguments to be skipped,
- * i.e., words in the "command name". */
-{
- register Proc *procPtr = framePtr->procPtr;
- register Var *varPtr;
- register CompiledLocal *localPtr;
- int localCt, numArgs, argCt, i, imax, result;
- Var *compiledLocals;
- Tcl_Obj *const *argObjs;
- int isMethod = (framePtr->isProcCallFrame &
- (FRAME_IS_METHOD | FRAME_IS_CONSTRUCTOR | FRAME_IS_DESTRUCTOR));
-
/*
* Create the "compiledLocals" array. Make sure it is large enough to hold
* all the procedure's compiled local variables, including its formal
@@ -1257,8 +1229,8 @@ TclObjInterpProcCore(
*/
numArgs = procPtr->numArgs;
- argCt = framePtr->objc-skip; /* set it to the number of args to the proc */
- argObjs = &framePtr->objv[skip];
+ argCt = objc-skip; /* set it to the number of args to the proc */
+ argObjs = &objv[skip];
varPtr = framePtr->compiledLocals;
localPtr = procPtr->firstLocalPtr;
if (numArgs == 0) {
@@ -1342,7 +1314,7 @@ TclObjInterpProcCore(
incorrectArgs:
codePtr = (ByteCode *) procPtr->bodyPtr->internalRep.otherValuePtr;
- InitCompiledLocals(interp, codePtr, localPtr, varPtr, framePtr->nsPtr);
+ InitCompiledLocals(interp, codePtr, localPtr, varPtr, nsPtr);
/*
* Build up desired argument list for Tcl_WrongNumArgs
@@ -1352,9 +1324,9 @@ TclObjInterpProcCore(
ckalloc(sizeof(Tcl_Obj *) * (unsigned)(numArgs+1));
#ifdef AVOID_HACKS_FOR_ITCL
- desiredObjs[0] = framePtr->objv[0];
+ desiredObjs[0] = objv[0];
#else
- desiredObjs[0] = Tcl_NewListObj(skip, framePtr->objv);
+ desiredObjs[0] = Tcl_NewListObj(skip, objv);
#endif /* AVOID_HACKS_FOR_ITCL */
localPtr = procPtr->firstLocalPtr;
@@ -1408,7 +1380,7 @@ TclObjInterpProcCore(
ByteCode *codePtr = (ByteCode *)
procPtr->bodyPtr->internalRep.otherValuePtr;
- InitCompiledLocals(interp, codePtr, localPtr, varPtr, framePtr->nsPtr);
+ InitCompiledLocals(interp, codePtr, localPtr, varPtr, nsPtr);
}
/*
@@ -1418,8 +1390,8 @@ TclObjInterpProcCore(
#ifdef TCL_COMPILE_DEBUG
if (tclTraceExec >= 1) {
fprintf(stdout, "Calling proc ");
- for (i = 0; i < framePtr->objc; i++) {
- TclPrintObject(stdout, framePtr->objv[i], 15);
+ for (i = 0; i < objc; i++) {
+ TclPrintObject(stdout, objv[i], 15);
fprintf(stdout, " ");
}
fprintf(stdout, "\n");
@@ -1436,19 +1408,19 @@ TclObjInterpProcCore(
if (result != TCL_OK) {
if (skip == 1) {
- result = ProcessProcResultCode(interp, procNameObj, result,
- isMethod);
+ result = ProcessProcResultCode(interp, procName, nameLen, result);
} else {
/*
* Use a 'procName' that contains the first skip elements of objv
* for error reporting. This insures that we do not see just
* 'apply', but also the lambda expression that caused the error.
*/
-
+
Tcl_Obj *namePtr;
- namePtr = Tcl_NewListObj(skip, framePtr->objv);
- result = ProcessProcResultCode(interp, namePtr, result, isMethod);
+ namePtr = Tcl_NewListObj(skip, objv);
+ procName = Tcl_GetStringFromObj(namePtr, &nameLen);
+ result = ProcessProcResultCode(interp, procName, nameLen, result);
TclDecrRefCount(namePtr);
}
}
@@ -1502,8 +1474,8 @@ TclProcCompileProc(
* but could be any code fragment compiled in
* the context of this procedure.) */
Namespace *nsPtr, /* Namespace containing procedure. */
- const char *description, /* string describing this body of code. */
- const char *procName) /* Name of this procedure. */
+ CONST char *description, /* string describing this body of code. */
+ CONST char *procName) /* Name of this procedure. */
{
return ProcCompileProc(interp, procPtr, bodyPtr, nsPtr, description,
procName, NULL);
@@ -1708,11 +1680,10 @@ static int
ProcessProcResultCode(
Tcl_Interp *interp, /* The interpreter in which the procedure was
* called and returned returnCode. */
- Tcl_Obj *procNameObj, /* Name of the procedure. Used for error
+ char *procName, /* Name of the procedure. Used for error
* messages and trace information. */
- int returnCode, /* The unexpected result code. */
- int isMethod) /* Whether this is a procedure, method,
- * constructor or destructor. */
+ int nameLen, /* Number of bytes in procedure's name. */
+ int returnCode) /* The unexpected result code. */
{
Interp *iPtr = (Interp *) interp;
int overflow, limit = 60;
@@ -1732,111 +1703,10 @@ ProcessProcResultCode(
((returnCode == TCL_BREAK) ? "break" : "continue"),
"\" outside of a loop", NULL);
}
- if (isMethod & FRAME_IS_CONSTRUCTOR) {
- if (interp->errorLine != 0xDEADBEEF) { /* hack! */
- CallContext *contextPtr =
- ((Interp *) interp)->varFramePtr->ooContextPtr;
- Method *mPtr = contextPtr->callChain[contextPtr->index].mPtr;
- Tcl_Command declarer;
- Tcl_Obj *objectNameObj;
- const char *objectName, *kindName;
- int objectNameLen;
-
- if (mPtr->declaringObjectPtr != NULL) {
- declarer = mPtr->declaringObjectPtr->command;
- kindName = "object";
- } else {
- if (mPtr->declaringClassPtr == NULL) {
- Tcl_Panic("method not declared in class or object");
- }
- declarer = mPtr->declaringClassPtr->thisPtr->command;
- kindName = "class";
- }
- TclNewObj(objectNameObj);
- Tcl_GetCommandFullName(interp, declarer, objectNameObj);
- objectName = Tcl_GetStringFromObj(objectNameObj, &objectNameLen);
- overflow = (objectNameLen > limit);
-
- TclFormatToErrorInfo(interp,
- "\n (%s \"%.*s%s\" constructor line %d)",
- kindName, (overflow ? limit : objectNameLen), objectName,
- (overflow ? "..." : ""), interp->errorLine);
-
- TclDecrRefCount(objectNameObj);
- }
- } else if (isMethod & FRAME_IS_DESTRUCTOR) {
- CallContext *contextPtr =
- ((Interp *) interp)->varFramePtr->ooContextPtr;
- Method *mPtr = contextPtr->callChain[contextPtr->index].mPtr;
- Tcl_Command declarer;
- Tcl_Obj *objectNameObj;
- const char *objectName, *kindName;
- int objectNameLen;
-
- if (mPtr->declaringObjectPtr != NULL) {
- declarer = mPtr->declaringObjectPtr->command;
- kindName = "object";
- } else {
- if (mPtr->declaringClassPtr == NULL) {
- Tcl_Panic("method not declared in class or object");
- }
- declarer = mPtr->declaringClassPtr->thisPtr->command;
- kindName = "class";
- }
- TclNewObj(objectNameObj);
- Tcl_GetCommandFullName(interp, declarer, objectNameObj);
- objectName = Tcl_GetStringFromObj(objectNameObj, &objectNameLen);
- overflow = (objectNameLen > limit);
-
- TclFormatToErrorInfo(interp,
- "\n (%s \"%.*s%s\" destructor line %d)",
- kindName, (overflow ? limit : objectNameLen), objectName,
- (overflow ? "..." : ""), interp->errorLine);
-
- TclDecrRefCount(objectNameObj);
- } else if (isMethod & FRAME_IS_METHOD) {
- int nameLen, objectNameLen, objNameOverflow;
- CallContext *contextPtr =
- ((Interp *) interp)->varFramePtr->ooContextPtr;
- Method *mPtr = contextPtr->callChain[contextPtr->index].mPtr;
- Tcl_Obj *objectNameObj;
- const char *objectName, *kindName, *methodName =
- Tcl_GetStringFromObj(mPtr->namePtr, &nameLen);
- Tcl_Command declarer;
-
- if (mPtr->declaringObjectPtr != NULL) {
- declarer = mPtr->declaringObjectPtr->command;
- kindName = "object";
- } else {
- if (mPtr->declaringClassPtr == NULL) {
- Tcl_Panic("method not declared in class or object");
- }
- declarer = mPtr->declaringClassPtr->thisPtr->command;
- kindName = "class";
- }
- TclNewObj(objectNameObj);
- Tcl_GetCommandFullName(interp, declarer, objectNameObj);
- objectName = Tcl_GetStringFromObj(objectNameObj, &objectNameLen);
- overflow = (nameLen > limit);
- objNameOverflow = (objectNameLen > limit);
-
- TclFormatToErrorInfo(interp,
- "\n (%s \"%.*s%s\" method \"%.*s%s\" line %d)", kindName,
- (objNameOverflow ? limit : objectNameLen), objectName,
- (objNameOverflow ? "..." : ""), (overflow ? limit : nameLen),
- methodName, (overflow ? "..." : ""), interp->errorLine);
-
- TclDecrRefCount(objectNameObj);
- } else {
- int nameLen;
- const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen);
-
overflow = (nameLen > limit);
-
TclFormatToErrorInfo(interp, "\n (procedure \"%.*s%s\" line %d)",
(overflow ? limit : nameLen), procName,
(overflow ? "..." : ""), interp->errorLine);
- }
return TCL_ERROR;
}
@@ -2098,11 +1968,11 @@ DupLambdaInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
register Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
- Proc *procPtr = srcPtr->internalRep.twoPtrValue.ptr1;
- Tcl_Obj *nsObjPtr = srcPtr->internalRep.twoPtrValue.ptr2;
+ Proc *procPtr = (Proc *) srcPtr->internalRep.twoPtrValue.ptr1;
+ Tcl_Obj *nsObjPtr = (Tcl_Obj *) srcPtr->internalRep.twoPtrValue.ptr2;
- copyPtr->internalRep.twoPtrValue.ptr1 = procPtr;
- copyPtr->internalRep.twoPtrValue.ptr2 = nsObjPtr;
+ copyPtr->internalRep.twoPtrValue.ptr1 = (void *) procPtr;
+ copyPtr->internalRep.twoPtrValue.ptr2 = (void *) nsObjPtr;
procPtr->refCount++;
Tcl_IncrRefCount(nsObjPtr);
@@ -2114,8 +1984,8 @@ FreeLambdaInternalRep(
register Tcl_Obj *objPtr) /* CmdName object with internal representation
* to free. */
{
- Proc *procPtr = objPtr->internalRep.twoPtrValue.ptr1;
- Tcl_Obj *nsObjPtr = objPtr->internalRep.twoPtrValue.ptr2;
+ Proc *procPtr = (Proc *) objPtr->internalRep.twoPtrValue.ptr1;
+ Tcl_Obj *nsObjPtr = (Tcl_Obj *) objPtr->internalRep.twoPtrValue.ptr2;
procPtr->refCount--;
if (procPtr->refCount == 0) {
@@ -2163,7 +2033,7 @@ SetLambdaFromAny(
bodyPtr, &procPtr) != TCL_OK) {
TclFormatToErrorInfo(interp,
"\n (parsing lambda expression \"%s\")",
- TclGetString(objPtr), NULL);
+ Tcl_GetString(objPtr), NULL);
return TCL_ERROR;
}
@@ -2200,35 +2070,18 @@ SetLambdaFromAny(
objPtr->typePtr->freeIntRepProc(objPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = procPtr;
- objPtr->internalRep.twoPtrValue.ptr2 = nsObjPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) procPtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = (void *) nsObjPtr;
objPtr->typePtr = &lambdaType;
return TCL_OK;
}
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_ApplyObjCmd --
- *
- * This object-based function is invoked to process the "apply" Tcl
- * command. See the user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl object result value.
- *
- * Side effects:
- * Depends on the content of the lambda term (i.e., objv[1]).
- *
- *----------------------------------------------------------------------
- */
-
int
Tcl_ApplyObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr = NULL;
@@ -2249,7 +2102,7 @@ Tcl_ApplyObjCmd(
lambdaPtr = objv[1];
if (lambdaPtr->typePtr == &lambdaType) {
- procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1;
+ procPtr = (Proc *) lambdaPtr->internalRep.twoPtrValue.ptr1;
}
#define JOE_EXTENSION 0
@@ -2276,7 +2129,7 @@ Tcl_ApplyObjCmd(
if (result != TCL_OK) {
return result;
}
- procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1;
+ procPtr = (Proc *) lambdaPtr->internalRep.twoPtrValue.ptr1;
}
procPtr->cmdPtr = &cmd;
@@ -2285,7 +2138,7 @@ Tcl_ApplyObjCmd(
* for that namespace. Note that TclObjInterpProc() will pop it.
*/
- nsObjPtr = lambdaPtr->internalRep.twoPtrValue.ptr2;
+ nsObjPtr = (Tcl_Obj *) lambdaPtr->internalRep.twoPtrValue.ptr2;
result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
if (result != TCL_OK) {
return result;