⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclproc.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
	    varPtr->value.objPtr = objPtr;	    varPtr->flags &= ~VAR_UNDEFINED;	    Tcl_IncrRefCount(objPtr);  /* since the local variable now has					* another reference to object. */	} else {	    Tcl_ResetResult(interp);	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),		    "no value given for parameter \"", localPtr->name,		    "\" to \"", Tcl_GetStringFromObj(objv[0], (int *) NULL),		    "\"", (char *) NULL);	    result = TCL_ERROR;	    goto procDone;	}	varPtr++;	localPtr = localPtr->nextPtr;    }    if (argCt > 0) {	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),		"called \"", Tcl_GetStringFromObj(objv[0], (int *) NULL),		"\" with too many arguments", (char *) NULL);	result = TCL_ERROR;	goto procDone;    }    /*     * Invoke the commands in the procedure's body.     */    if (tclTraceExec >= 1) {	fprintf(stdout, "Calling proc ");	for (i = 0;  i < objc;  i++) {	    bytes = Tcl_GetStringFromObj(objv[i], &length);	    TclPrintSource(stdout, bytes, TclMin(length, 15));	    fprintf(stdout, " ");	}	fprintf(stdout, "\n");	fflush(stdout);    }    iPtr->returnCode = TCL_OK;    procPtr->refCount++;    result = Tcl_EvalObj(interp, procPtr->bodyPtr);    procPtr->refCount--;    if (procPtr->refCount <= 0) {	TclProcCleanupProc(procPtr);    }    if (result != TCL_OK) {	if (result == TCL_RETURN) {	    result = TclUpdateReturnInfo(iPtr);	} else if (result == TCL_ERROR) {	    char msg[100];	    sprintf(msg, "\n    (procedure \"%.50s\" line %d)",		    procName, iPtr->errorLine);	    Tcl_AddObjErrorInfo(interp, msg, -1);	} else if (result == TCL_BREAK) {	    Tcl_ResetResult(interp);	    Tcl_AppendToObj(Tcl_GetObjResult(interp),	            "invoked \"break\" outside of a loop", -1);	    result = TCL_ERROR;	} else if (result == TCL_CONTINUE) {	    Tcl_ResetResult(interp);	    Tcl_AppendToObj(Tcl_GetObjResult(interp),		    "invoked \"continue\" outside of a loop", -1);	    result = TCL_ERROR;	}    }        procDone:    /*     * Pop and free the call frame for this procedure invocation.     */        Tcl_PopCallFrame(interp);        /*     * Free the compiledLocals array if malloc'ed storage was used.     */    if (compiledLocals != localStorage) {	ckfree((char *) compiledLocals);    }    return result;#undef NUM_LOCALS}/* *---------------------------------------------------------------------- * * TclProcCompileProc -- * *	Called just before a procedure is executed to compile the *	body to byte codes.  If the type of the body is not *	"byte code" or if the compile conditions have changed *	(namespace context, epoch counters, etc.) then the body *	is recompiled.  Otherwise, this procedure does nothing. * * Results: *	None. * * Side effects: *	May change the internal representation of the body object *	to compiled code. * *---------------------------------------------------------------------- */ intTclProcCompileProc(interp, procPtr, bodyPtr, nsPtr, description, procName)    Tcl_Interp *interp;		/* Interpreter containing procedure. */    Proc *procPtr;		/* Data associated with procedure. */    Tcl_Obj *bodyPtr;		/* Body of proc. (Usually procPtr->bodyPtr, 				 * 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. */{    Interp *iPtr = (Interp*)interp;    int result;    Tcl_CallFrame frame;    Proc *saveProcPtr;    ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;     /*     * If necessary, compile the procedure's body. The compiler will     * allocate frame slots for the procedure's non-argument local     * variables. If the ByteCode already exists, make sure it hasn't been     * invalidated by someone redefining a core command (this might make the     * compiled code wrong). Also, if the code was compiled in/for a     * different interpreter, we recompile it. Note that compiling the body     * might increase procPtr->numCompiledLocals if new local variables are     * found while compiling.     *     * Precompiled procedure bodies, however, are immutable and therefore     * they are not recompiled, even if things have changed.     */     if (bodyPtr->typePtr == &tclByteCodeType) { 	if ((codePtr->iPtr != iPtr) 	        || (codePtr->compileEpoch != iPtr->compileEpoch) 	        || (codePtr->nsPtr != nsPtr)) {            if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {                if (codePtr->iPtr != iPtr) {                    Tcl_AppendResult(interp,                            "a precompiled script jumped interps", NULL);                    return TCL_ERROR;                }	        codePtr->compileEpoch = iPtr->compileEpoch;                codePtr->nsPtr = nsPtr;            } else {                tclByteCodeType.freeIntRepProc(bodyPtr);                bodyPtr->typePtr = (Tcl_ObjType *) NULL;            } 	}    }    if (bodyPtr->typePtr != &tclByteCodeType) { 	char buf[100]; 	int numChars; 	char *ellipsis; 	 	if (tclTraceCompile >= 1) { 	    /* 	     * Display a line summarizing the top level command we 	     * are about to compile. 	     */  	    numChars = strlen(procName); 	    ellipsis = ""; 	    if (numChars > 50) { 		numChars = 50; 		ellipsis = "..."; 	    } 	    fprintf(stdout, "Compiling %s \"%.*s%s\"\n", 		    description, numChars, procName, ellipsis); 	} 	 	/* 	 * Plug the current procPtr into the interpreter and coerce 	 * the code body to byte codes.  The interpreter needs to 	 * know which proc it's compiling so that it can access its 	 * list of compiled locals. 	 * 	 * TRICKY NOTE:  Be careful to push a call frame with the 	 *   proper namespace context, so that the byte codes are 	 *   compiled in the appropriate class context. 	 */  	saveProcPtr = iPtr->compiledProcPtr; 	iPtr->compiledProcPtr = procPtr;  	result = Tcl_PushCallFrame(interp, &frame,		(Tcl_Namespace*)nsPtr, /* isProcCallFrame */ 0);  	if (result == TCL_OK) {	    result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);	    Tcl_PopCallFrame(interp);	}  	iPtr->compiledProcPtr = saveProcPtr; 	 	if (result != TCL_OK) { 	    if (result == TCL_ERROR) { 		numChars = strlen(procName); 		ellipsis = ""; 		if (numChars > 50) { 		    numChars = 50; 		    ellipsis = "..."; 		} 		sprintf(buf, "\n    (compiling %s \"%.*s%s\", line %d)", 			description, numChars, procName, ellipsis, 			interp->errorLine); 		Tcl_AddObjErrorInfo(interp, buf, -1); 	    } 	    return result; 	}    } else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {	register CompiledLocal *localPtr; 		/*	 * The resolver epoch has changed, but we only need to invalidate	 * the resolver cache.	 */	for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;	    localPtr = localPtr->nextPtr) {	    localPtr->flags &= ~(VAR_RESOLVED);	    if (localPtr->resolveInfo) {		if (localPtr->resolveInfo->deleteProc) {		    localPtr->resolveInfo->deleteProc(localPtr->resolveInfo);		} else {		    ckfree((char*)localPtr->resolveInfo);		}		localPtr->resolveInfo = NULL;	    }	}    }    return TCL_OK;} /* *---------------------------------------------------------------------- * * TclProcDeleteProc -- * *	This procedure is invoked just before a command procedure is *	removed from an interpreter.  Its job is to release all the *	resources allocated to the procedure. * * Results: *	None. * * Side effects: *	Memory gets freed, unless the procedure is actively being *	executed.  In this case the cleanup is delayed until the *	last call to the current procedure completes. * *---------------------------------------------------------------------- */voidTclProcDeleteProc(clientData)    ClientData clientData;		/* Procedure to be deleted. */{    Proc *procPtr = (Proc *) clientData;    procPtr->refCount--;    if (procPtr->refCount <= 0) {	TclProcCleanupProc(procPtr);    }}/* *---------------------------------------------------------------------- * * TclProcCleanupProc -- * *	This procedure does all the real work of freeing up a Proc *	structure.  It's called only when the structure's reference *	count becomes zero. * * Results: *	None. * * Side effects: *	Memory gets freed. * *---------------------------------------------------------------------- */voidTclProcCleanupProc(procPtr)    register Proc *procPtr;		/* Procedure to be deleted. */{    register CompiledLocal *localPtr;    Tcl_Obj *bodyPtr = procPtr->bodyPtr;    Tcl_Obj *defPtr;    Tcl_ResolvedVarInfo *resVarInfo;    if (bodyPtr != NULL) {	Tcl_DecrRefCount(bodyPtr);    }    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;  ) {	CompiledLocal *nextPtr = localPtr->nextPtr;        resVarInfo = localPtr->resolveInfo;	if (resVarInfo) {	    if (resVarInfo->deleteProc) {		(*resVarInfo->deleteProc)(resVarInfo);	    } else {		ckfree((char *) resVarInfo);	    }        }	if (localPtr->defValuePtr != NULL) {	    defPtr = localPtr->defValuePtr;	    Tcl_DecrRefCount(defPtr);	}	ckfree((char *) localPtr);	localPtr = nextPtr;    }    ckfree((char *) procPtr);}/* *---------------------------------------------------------------------- * * TclUpdateReturnInfo -- * *	This procedure is called when procedures return, and at other *	points where the TCL_RETURN code is used.  It examines fields *	such as iPtr->returnCode and iPtr->errorCode and modifies *	the real return status accordingly. * * Results: *	The return value is the true completion code to use for *	the procedure, instead of TCL_RETURN. * * Side effects: *	The errorInfo and errorCode variables may get modified. * *---------------------------------------------------------------------- */intTclUpdateReturnInfo(iPtr)    Interp *iPtr;		/* Interpreter for which TCL_RETURN				 * exception is being processed. */{    int code;    code = iPtr->returnCode;    iPtr->returnCode = TCL_OK;    if (code == TCL_ERROR) {	Tcl_SetVar2((Tcl_Interp *) iPtr, "errorCode", (char *) NULL,		(iPtr->errorCode != NULL) ? iPtr->errorCode : "NONE",		TCL_GLOBAL_ONLY);	iPtr->flags |= ERROR_CODE_SET;	if (iPtr->errorInfo != NULL) {	    Tcl_SetVar2((Tcl_Interp *) iPtr, "errorInfo", (char *) NULL,		    iPtr->errorInfo, TCL_GLOBAL_ONLY);	    iPtr->flags |= ERR_IN_PROGRESS;	}    }    return code;}/* *---------------------------------------------------------------------- * * TclGetInterpProc -- * *  Returns a pointer to the TclProcInterpProc procedure; this is different *  from the value obtained from the TclProcInterpProc reference on systems *  like Windows where import and export versions of a procedure exported *  by a DLL exist. * * Results: *  Returns the internal address of the TclProcInterpProc procedure. * * Side effects: *  None. * *---------------------------------------------------------------------- */TclCmdProcTypeTclGetInterpProc(){    return TclProcInterpProc;}/* *---------------------------------------------------------------------- * * TclGetObjInterpProc -- * *  Returns a pointer to the TclObjInterpProc procedure; this is different *  from the value obtained from the TclObjInterpProc reference on systems *  like Windows where import and export versions of a procedure exported *  by a DLL exist. * * Results: *  Returns the internal address of the TclProcInterpProc procedure. * * Side effects: *  None. * *---------------------------------------------------------------------- */TclObjCmdProcTypeTclGetObjInterpProc(){    return TclObjInterpProc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -