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

📄 tclcompile.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	/*	 * Change the object into a ByteCode object. Ownership of the literal	 * objects and aux data items is given to the ByteCode object.	 */    #ifdef TCL_COMPILE_DEBUG	TclVerifyLocalLiteralTable(&compEnv);#endif /*TCL_COMPILE_DEBUG*/	TclInitByteCodeObj(objPtr, &compEnv);#ifdef TCL_COMPILE_DEBUG	if (tclTraceCompile >= 2) {	    TclPrintByteCodeObj(interp, objPtr);	}#endif /* TCL_COMPILE_DEBUG */    }	    if (result != TCL_OK) {	/*	 * Compilation errors. 	 */	entryPtr = compEnv.literalArrayPtr;	for (i = 0;  i < compEnv.literalArrayNext;  i++) {	    TclReleaseLiteral(interp, entryPtr->objPtr);	    entryPtr++;	}#ifdef TCL_COMPILE_DEBUG	TclVerifyGlobalLiteralTable(iPtr);#endif /*TCL_COMPILE_DEBUG*/	auxDataPtr = compEnv.auxDataArrayPtr;	for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {	    if (auxDataPtr->type->freeProc != NULL) {		auxDataPtr->type->freeProc(auxDataPtr->clientData);	    }	    auxDataPtr++;	}    }    /*     * Free storage allocated during compilation.     */        if (localTablePtr->buckets != localTablePtr->staticBuckets) {	ckfree((char *) localTablePtr->buckets);    }    TclFreeCompileEnv(&compEnv);    return result;}/* *----------------------------------------------------------------------- * * SetByteCodeFromAny -- * *	Part of the bytecode Tcl object type implementation. Attempts to *	generate an byte code internal form for the Tcl object "objPtr" by *	compiling its string representation. * * Results: *	The return value is a standard Tcl object result. If an error occurs *	during compilation, an error message is left in the interpreter's *	result unless "interp" is NULL. * * Side effects: *	Frees the old internal representation. If no error occurs, then the *	compiled code is stored as "objPtr"s bytecode representation. *	Also, if debugging, initializes the "tcl_traceCompile" Tcl variable *	used to trace compilations. * *---------------------------------------------------------------------- */static intSetByteCodeFromAny(interp, objPtr)    Tcl_Interp *interp;		/* The interpreter for which the code is				 * being compiled.  Must not be NULL. */    Tcl_Obj *objPtr;		/* The object to make a ByteCode object. */{    return TclSetByteCodeFromAny(interp, objPtr,	    (CompileHookProc *) NULL, (ClientData) NULL);}/* *---------------------------------------------------------------------- * * DupByteCodeInternalRep -- * *	Part of the bytecode Tcl object type implementation. However, it *	does not copy the internal representation of a bytecode Tcl_Obj, but *	instead leaves the new object untyped (with a NULL type pointer). *	Code will be compiled for the new object only if necessary. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */static voidDupByteCodeInternalRep(srcPtr, copyPtr)    Tcl_Obj *srcPtr;		/* Object with internal rep to copy. */    Tcl_Obj *copyPtr;		/* Object with internal rep to set. */{    return;}/* *---------------------------------------------------------------------- * * FreeByteCodeInternalRep -- * *	Part of the bytecode Tcl object type implementation. Frees the *	storage associated with a bytecode object's internal representation *	unless its code is actively being executed. * * Results: *	None. * * Side effects: *	The bytecode object's internal rep is marked invalid and its *	code gets freed unless the code is actively being executed. *	In that case the cleanup is delayed until the last execution *	of the code completes. * *---------------------------------------------------------------------- */static voidFreeByteCodeInternalRep(objPtr)    register Tcl_Obj *objPtr;	/* Object whose internal rep to free. */{    register ByteCode *codePtr =	    (ByteCode *) objPtr->internalRep.otherValuePtr;    codePtr->refCount--;    if (codePtr->refCount <= 0) {	TclCleanupByteCode(codePtr);    }    objPtr->typePtr = NULL;    objPtr->internalRep.otherValuePtr = NULL;}/* *---------------------------------------------------------------------- * * TclCleanupByteCode -- * *	This procedure does all the real work of freeing up a bytecode *	object's ByteCode structure. It's called only when the structure's *	reference count becomes zero. * * Results: *	None. * * Side effects: *	Frees objPtr's bytecode internal representation and sets its type *	and objPtr->internalRep.otherValuePtr NULL. Also releases its *	literals and frees its auxiliary data items. * *---------------------------------------------------------------------- */voidTclCleanupByteCode(codePtr)    register ByteCode *codePtr;	/* Points to the ByteCode to free. */{    Tcl_Interp *interp = (Tcl_Interp *) *codePtr->interpHandle;    int numLitObjects = codePtr->numLitObjects;    int numAuxDataItems = codePtr->numAuxDataItems;    register Tcl_Obj **objArrayPtr;    register AuxData *auxDataPtr;    int i;#ifdef TCL_COMPILE_STATS    if (interp != NULL) {	ByteCodeStats *statsPtr;	Tcl_Time destroyTime;	int lifetimeSec, lifetimeMicroSec, log2;	statsPtr = &((Interp *) interp)->stats;	statsPtr->numByteCodesFreed++;	statsPtr->currentSrcBytes -= (double) codePtr->numSrcBytes;	statsPtr->currentByteCodeBytes -= (double) codePtr->structureSize;	statsPtr->currentInstBytes   -= (double) codePtr->numCodeBytes;	statsPtr->currentLitBytes    -=		(double) (codePtr->numLitObjects * sizeof(Tcl_Obj *)); 	statsPtr->currentExceptBytes -=		(double) (codePtr->numExceptRanges * sizeof(ExceptionRange));	statsPtr->currentAuxBytes    -=		(double) (codePtr->numAuxDataItems * sizeof(AuxData));	statsPtr->currentCmdMapBytes -= (double) codePtr->numCmdLocBytes;	Tcl_GetTime(&destroyTime);	lifetimeSec = destroyTime.sec - codePtr->createTime.sec;	if (lifetimeSec > 2000) {	/* avoid overflow */	    lifetimeSec = 2000;	}	lifetimeMicroSec =	    1000000*lifetimeSec + (destroyTime.usec - codePtr->createTime.usec);		log2 = TclLog2(lifetimeMicroSec);	if (log2 > 31) {	    log2 = 31;	}	statsPtr->lifetimeCount[log2]++;    }#endif /* TCL_COMPILE_STATS */    /*     * A single heap object holds the ByteCode structure and its code,     * object, command location, and auxiliary data arrays. This means we     * only need to 1) decrement the ref counts of the LiteralEntry's in     * its literal array, 2) call the free procs for the auxiliary data     * items, and 3) free the ByteCode structure's heap object.     *     * The case for TCL_BYTECODE_PRECOMPILED (precompiled ByteCodes,     * like those generated from tbcload) is special, as they doesn't     * make use of the global literal table.  They instead maintain     * private references to their literals which must be decremented.     */    if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {	register Tcl_Obj *objPtr; 	objArrayPtr = codePtr->objArrayPtr;	for (i = 0;  i < numLitObjects;  i++) {	    objPtr = *objArrayPtr;	    if (objPtr) {		Tcl_DecrRefCount(objPtr);	    }	    objArrayPtr++;	}	codePtr->numLitObjects = 0;    } else if (interp != NULL) {	/*	 * If the interp has already been freed, then Tcl will have already 	 * forcefully released all the literals used by ByteCodes compiled	 * with respect to that interp.	 */	 	objArrayPtr = codePtr->objArrayPtr;	for (i = 0;  i < numLitObjects;  i++) {	    /*	     * TclReleaseLiteral sets a ByteCode's object array entry NULL to	     * indicate that it has already freed the literal.	     */	    	    if (*objArrayPtr != NULL) {		TclReleaseLiteral(interp, *objArrayPtr);	    }	    objArrayPtr++;	}    }        auxDataPtr = codePtr->auxDataArrayPtr;    for (i = 0;  i < numAuxDataItems;  i++) {	if (auxDataPtr->type->freeProc != NULL) {	    (*auxDataPtr->type->freeProc)(auxDataPtr->clientData);	}	auxDataPtr++;    }    TclHandleRelease(codePtr->interpHandle);    ckfree((char *) codePtr);}/* *---------------------------------------------------------------------- * * TclInitCompileEnv -- * *	Initializes a CompileEnv compilation environment structure for the *	compilation of a string in an interpreter. * * Results: *	None. * * Side effects: *	The CompileEnv structure is initialized. * *---------------------------------------------------------------------- */voidTclInitCompileEnv(interp, envPtr, string, numBytes)    Tcl_Interp *interp;		 /* The interpreter for which a CompileEnv				  * structure is initialized. */    register CompileEnv *envPtr; /* Points to the CompileEnv structure to				  * initialize. */    char *string;		 /* The source string to be compiled. */    int numBytes;		 /* Number of bytes in source string. */{    Interp *iPtr = (Interp *) interp;        envPtr->iPtr = iPtr;    envPtr->source = string;    envPtr->numSrcBytes = numBytes;    envPtr->procPtr = iPtr->compiledProcPtr;    envPtr->numCommands = 0;    envPtr->exceptDepth = 0;    envPtr->maxExceptDepth = 0;    envPtr->maxStackDepth = 0;    envPtr->currStackDepth = 0;    TclInitLiteralTable(&(envPtr->localLitTable));    envPtr->codeStart = envPtr->staticCodeSpace;    envPtr->codeNext = envPtr->codeStart;    envPtr->codeEnd = (envPtr->codeStart + COMPILEENV_INIT_CODE_BYTES);    envPtr->mallocedCodeArray = 0;    envPtr->literalArrayPtr = envPtr->staticLiteralSpace;    envPtr->literalArrayNext = 0;    envPtr->literalArrayEnd = COMPILEENV_INIT_NUM_OBJECTS;    envPtr->mallocedLiteralArray = 0;        envPtr->exceptArrayPtr = envPtr->staticExceptArraySpace;    envPtr->exceptArrayNext = 0;    envPtr->exceptArrayEnd = COMPILEENV_INIT_EXCEPT_RANGES;    envPtr->mallocedExceptArray = 0;        envPtr->cmdMapPtr = envPtr->staticCmdMapSpace;    envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE;    envPtr->mallocedCmdMap = 0;        envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace;    envPtr->auxDataArrayNext = 0;    envPtr->auxDataArrayEnd = COMPILEENV_INIT_AUX_DATA_SIZE;    envPtr->mallocedAuxDataArray = 0;}/* *---------------------------------------------------------------------- * * TclFreeCompileEnv -- * *	Free the storage allocated in a CompileEnv compilation environment *	structure. * * Results: *	None. *  * Side effects: *	Allocated storage in the CompileEnv structure is freed. Note that *	its local literal table is not deleted and its literal objects are *	not released. In addition, storage referenced by its auxiliary data *	items is not freed. This is done so that, when compilation is *	successful, "ownership" of these objects and aux data items is *	handed over to the corresponding ByteCode structure. * *---------------------------------------------------------------------- */voidTclFreeCompileEnv(envPtr)    register CompileEnv *envPtr; /* Points to the CompileEnv structure. */{    if (envPtr->mallocedCodeArray) {	ckfree((char *) envPtr->codeStart);    }    if (envPtr->mallocedLiteralArray) {	ckfree((char *) envPtr->literalArrayPtr);    }    if (envPtr->mallocedExceptArray) {	ckfree((char *) envPtr->exceptArrayPtr);    }    if (envPtr->mallocedCmdMap) {	ckfree((char *) envPtr->cmdMapPtr);    }    if (envPtr->mallocedAuxDataArray) {	ckfree((char *) envPtr->auxDataArrayPtr);    }}/* *---------------------------------------------------------------------- * * TclCompileScript -- * *	Compile a Tcl script in a string. * * Results: *	The return value is TCL_OK on a successful compilation and TCL_ERROR *	on failure. If TCL_ERROR is returned, then the interpreter's result

⌨️ 快捷键说明

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