int TclOO_Object_Eval( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { CallContext *contextPtr = (CallContext *) context; Tcl_Object object = Tcl_ObjectContextObject(context); register const int skip = Tcl_ObjectContextSkippedArgs(context); CallFrame *framePtr, **framePtrPtr = &framePtr; Tcl_Obj *scriptPtr; CmdFrame *invoker; if (objc-1 < skip) { Tcl_WrongNumArgs(interp, skip, objv, "arg ?arg ...?"); return TCL_ERROR; } /* * Make the object's namespace the current namespace and evaluate the * command(s). */ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr, Tcl_GetObjectNamespace(object), 0); framePtr->objc = objc; framePtr->objv = objv; /* Reference counts do not need to be * incremented here. */ if (!(contextPtr->callPtr->flags & PUBLIC_METHOD)) { object = NULL; /* Now just for error mesage printing. */ } /* * Work out what script we are actually going to evaluate. * * When there's more than one argument, we concatenate them together with * spaces between, then evaluate the result. Tcl_EvalObjEx will delete the * object when it decrements its refcount after eval'ing it. */ if (objc != skip+1) { scriptPtr = Tcl_ConcatObj(objc-skip, objv+skip); invoker = NULL; } else { scriptPtr = objv[skip]; invoker = ((Interp *) interp)->cmdFramePtr; } /* * Evaluate the script now, with FinalizeEval to do the processing after * the script completes. */ TclNRAddCallback(interp, FinalizeEval, object, NULL, NULL, NULL); return TclNREvalObjEx(interp, scriptPtr, 0, invoker, skip); }
static int Tcl_InvokeClassProcedureMethod( Tcl_Interp *interp, Tcl_Obj *namePtr, /* name of the method */ Tcl_Namespace *nsPtr, /* namespace for calling method */ ProcedureMethod *pmPtr, /* method type specific data */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Arguments as actually seen. */ { 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(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. */ if (pmPtr->postCallProc) { Tcl_NRAddCallback(interp, CallFinalizePMCall, nsPtr, (Tcl_NRPostProc *)pmPtr->postCallProc, pmPtr->clientData, NULL); } return TclNRInterpProcCore(interp, namePtr, 1, pmPtr->errProc); done: return result; }