Attachment "classmethodinvoke.c" to
ticket [1865198fff]
added by
wiede
2008-01-07 00:27:02.
int
Tcl_InvokeClassProcedureMethod(
ClientData clientData, /* Pointer to some per-method context. */
Tcl_Interp *interp,
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Arguments as actually seen. */
{
Method *mPtr = clientData;
Tcl_Namespace *nsPtr = mPtr->declaringClassPtr->thisPtr->namespacePtr;
ProcedureMethod *pmPtr = mPtr->clientData;
Proc *procPtr = pmPtr->procPtr;
int flags = FRAME_IS_METHOD;
CallFrame frame;
CallFrame *framePtr = &frame;
CallFrame **framePtrPtr1 = &framePtr;
Tcl_CallFrame **framePtrPtr = (Tcl_CallFrame **)framePtrPtr1;
Command cmd;
int result;
memset(&cmd, 0, sizeof(Command));
cmd.nsPtr = (Namespace *) nsPtr;
cmd.clientData = NULL;
pmPtr->procPtr->cmdPtr = &cmd;
result = TclProcCompileProc(interp, pmPtr->procPtr,
pmPtr->procPtr->bodyPtr, (Namespace *) nsPtr, "body of method",
Tcl_GetString(mPtr->namePtr));
if (result != TCL_OK) {
return result;
}
/*
* Make the stack frame and fill it out with information about this call.
* This operation may fail.
*/
flags |= FRAME_IS_PROC;
result = TclPushStackFrame(interp, framePtrPtr, nsPtr, flags);
if (result != TCL_OK) {
return result;
}
framePtr->clientData = NULL;
framePtr->objc = objc;
framePtr->objv = objv;
framePtr->procPtr = procPtr;
/*
* Give the pre-call callback a chance to do some setup and, possibly,
* veto the call.
*/
if (pmPtr->preCallProc != NULL) {
int isFinished;
result = pmPtr->preCallProc(pmPtr->clientData, interp, NULL,
(Tcl_CallFrame *) framePtr, &isFinished);
if (isFinished || result != TCL_OK) {
Tcl_PopCallFrame(interp);
TclStackFree(interp, framePtr);
goto done;
}
}
/*
* Now invoke the body of the method. Note that we need to take special
* action when doing unknown processing to ensure that the missing method
* name is passed as an argument.
*/
result = TclObjInterpProcCore(interp, mPtr->namePtr, 1, pmPtr->errProc);
/*
* Give the post-call callback a chance to do some cleanup. Note that at
* this point the call frame itself is invalid; it's already been popped.
*/
if (pmPtr->postCallProc) {
result = pmPtr->postCallProc(pmPtr->clientData, interp, NULL,
nsPtr, result);
}
done:
return result;
}