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

📄 tclcompile.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
        p = (unsigned char *) ckalloc((size_t) structureSize);    codePtr = (ByteCode *) p;    codePtr->interpHandle = TclHandlePreserve(iPtr->handle);    codePtr->compileEpoch = iPtr->compileEpoch;    codePtr->nsPtr = namespacePtr;    codePtr->nsEpoch = namespacePtr->resolverEpoch;    codePtr->refCount = 1;    codePtr->flags = 0;    codePtr->source = envPtr->source;    codePtr->procPtr = envPtr->procPtr;    codePtr->numCommands = envPtr->numCommands;    codePtr->numSrcBytes = envPtr->numSrcBytes;    codePtr->numCodeBytes = codeBytes;    codePtr->numLitObjects = numLitObjects;    codePtr->numExceptRanges = envPtr->exceptArrayNext;    codePtr->numAuxDataItems = envPtr->auxDataArrayNext;    codePtr->numCmdLocBytes = cmdLocBytes;    codePtr->maxExceptDepth = envPtr->maxExceptDepth;    codePtr->maxStackDepth = envPtr->maxStackDepth;    p += sizeof(ByteCode);    codePtr->codeStart = p;    memcpy((VOID *) p, (VOID *) envPtr->codeStart, (size_t) codeBytes);        p += TCL_ALIGN(codeBytes);	      /* align object array */    codePtr->objArrayPtr = (Tcl_Obj **) p;    for (i = 0;  i < numLitObjects;  i++) {	codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr;    }    p += TCL_ALIGN(objArrayBytes);    /* align exception range array */    if (exceptArrayBytes > 0) {	codePtr->exceptArrayPtr = (ExceptionRange *) p;	memcpy((VOID *) p, (VOID *) envPtr->exceptArrayPtr,	        (size_t) exceptArrayBytes);    } else {	codePtr->exceptArrayPtr = NULL;    }        p += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */    if (auxDataArrayBytes > 0) {	codePtr->auxDataArrayPtr = (AuxData *) p;	memcpy((VOID *) p, (VOID *) envPtr->auxDataArrayPtr,	        (size_t) auxDataArrayBytes);    } else {	codePtr->auxDataArrayPtr = NULL;    }    p += auxDataArrayBytes;    nextPtr = EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);#ifdef TCL_COMPILE_DEBUG    if (((size_t)(nextPtr - p)) != cmdLocBytes) {		panic("TclInitByteCodeObj: encoded cmd location bytes %d != expected size %d\n", (nextPtr - p), cmdLocBytes);    }#endif        /*     * Record various compilation-related statistics about the new ByteCode     * structure. Don't include overhead for statistics-related fields.     */#ifdef TCL_COMPILE_STATS    codePtr->structureSize = structureSize	    - (sizeof(size_t) + sizeof(Tcl_Time));    Tcl_GetTime(&(codePtr->createTime));        RecordByteCodeStats(codePtr);#endif /* TCL_COMPILE_STATS */        /*     * Free the old internal rep then convert the object to a     * bytecode object by making its internal rep point to the just     * compiled ByteCode.     */	        if ((objPtr->typePtr != NULL) &&	    (objPtr->typePtr->freeIntRepProc != NULL)) {	(*objPtr->typePtr->freeIntRepProc)(objPtr);    }    objPtr->internalRep.otherValuePtr = (VOID *) codePtr;    objPtr->typePtr = &tclByteCodeType;}/* *---------------------------------------------------------------------- * * LogCompilationInfo -- * *	This procedure is invoked after an error occurs during compilation. *	It adds information to the "errorInfo" variable to describe the *	command that was being compiled when the error occurred. * * Results: *	None. * * Side effects: *	Information about the command is added to errorInfo and the *	line number stored internally in the interpreter is set.  If this *	is the first call to this procedure or Tcl_AddObjErrorInfo since *	an error occurred, then old information in errorInfo is *	deleted. * *---------------------------------------------------------------------- */static voidLogCompilationInfo(interp, script, command, length)    Tcl_Interp *interp;		/* Interpreter in which to log the				 * information. */    CONST char *script;		/* First character in script containing				 * command (must be <= command). */    CONST char *command;	/* First character in command that				 * generated the error. */    int length;			/* Number of bytes in command (-1 means				 * use all bytes up to first null byte). */{    char buffer[200];    register CONST char *p;    char *ellipsis = "";    Interp *iPtr = (Interp *) interp;    if (iPtr->flags & ERR_ALREADY_LOGGED) {	/*	 * Someone else has already logged error information for this	 * command; we shouldn't add anything more.	 */	return;    }    /*     * Compute the line number where the error occurred.     */    iPtr->errorLine = 1;    for (p = script; p != command; p++) {	if (*p == '\n') {	    iPtr->errorLine++;	}    }    /*     * Create an error message to add to errorInfo, including up to a     * maximum number of characters of the command.     */    if (length < 0) {	length = strlen(command);    }    if (length > 150) {	length = 150;	ellipsis = "...";    }    sprintf(buffer, "\n    while compiling\n\"%.*s%s\"",	    length, command, ellipsis);    Tcl_AddObjErrorInfo(interp, buffer, -1);}/* *---------------------------------------------------------------------- * * TclFindCompiledLocal -- * *	This procedure is called at compile time to look up and optionally *	allocate an entry ("slot") for a variable in a procedure's array of *	local variables. If the variable's name is NULL, a new temporary *	variable is always created. (Such temporary variables can only be *	referenced using their slot index.) * * Results: *	If create is 0 and the name is non-NULL, then if the variable is *	found, the index of its entry in the procedure's array of local *	variables is returned; otherwise -1 is returned. If name is NULL, *	the index of a new temporary variable is returned. Finally, if *	create is 1 and name is non-NULL, the index of a new entry is *	returned. * * Side effects: *	Creates and registers a new local variable if create is 1 and *	the variable is unknown, or if the name is NULL. * *---------------------------------------------------------------------- */intTclFindCompiledLocal(name, nameBytes, create, flags, procPtr)    register CONST char *name;	/* Points to first character of the name of				 * a scalar or array variable. If NULL, a				 * temporary var should be created. */    int nameBytes;		/* Number of bytes in the name. */    int create;			/* If 1, allocate a local frame entry for				 * the variable if it is new. */    int flags;			/* Flag bits for the compiled local if				 * created. Only VAR_SCALAR, VAR_ARRAY, and				 * VAR_LINK make sense. */    register Proc *procPtr;	/* Points to structure describing procedure				 * containing the variable reference. */{    register CompiledLocal *localPtr;    int localVar = -1;    register int i;    /*     * If not creating a temporary, does a local variable of the specified     * name already exist?     */    if (name != NULL) {		int localCt = procPtr->numCompiledLocals;	localPtr = procPtr->firstLocalPtr;	for (i = 0;  i < localCt;  i++) {	    if (!TclIsVarTemporary(localPtr)) {		char *localName = localPtr->name;		if ((nameBytes == localPtr->nameLength)	                && (strncmp(name, localName, (unsigned) nameBytes) == 0)) {		    return i;		}	    }	    localPtr = localPtr->nextPtr;	}    }    /*     * Create a new variable if appropriate.     */        if (create || (name == NULL)) {	localVar = procPtr->numCompiledLocals;	localPtr = (CompiledLocal *) ckalloc((unsigned) 	        (sizeof(CompiledLocal) - sizeof(localPtr->name)		+ nameBytes+1));	if (procPtr->firstLocalPtr == NULL) {	    procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;	} else {	    procPtr->lastLocalPtr->nextPtr = localPtr;	    procPtr->lastLocalPtr = localPtr;	}	localPtr->nextPtr = NULL;	localPtr->nameLength = nameBytes;	localPtr->frameIndex = localVar;	localPtr->flags = flags | VAR_UNDEFINED;	if (name == NULL) {	    localPtr->flags |= VAR_TEMPORARY;	}	localPtr->defValuePtr = NULL;	localPtr->resolveInfo = NULL;	if (name != NULL) {	    memcpy((VOID *) localPtr->name, (VOID *) name,	            (size_t) nameBytes);	}	localPtr->name[nameBytes] = '\0';	procPtr->numCompiledLocals++;    }    return localVar;}/* *---------------------------------------------------------------------- * * TclInitCompiledLocals -- * *	This routine is invoked in order to initialize the compiled *	locals table for a new call frame. * * Results: *	None. * * Side effects: *	May invoke various name resolvers in order to determine which *	variables are being referenced at runtime. * *---------------------------------------------------------------------- */voidTclInitCompiledLocals(interp, framePtr, nsPtr)    Tcl_Interp *interp;		/* Current interpreter. */    CallFrame *framePtr;	/* Call frame to initialize. */    Namespace *nsPtr;		/* Pointer to current namespace. */{    register CompiledLocal *localPtr;    Interp *iPtr = (Interp*) interp;    Tcl_ResolvedVarInfo *vinfo, *resVarInfo;    Var *varPtr = framePtr->compiledLocals;    Var *resolvedVarPtr;    ResolverScheme *resPtr;    int result;    /*     * Initialize the array of local variables stored in the call frame.     * Some variables may have special resolution rules.  In that case,     * we call their "resolver" procs to get our hands on the variable,     * and we make the compiled local a link to the real variable.     */    for (localPtr = framePtr->procPtr->firstLocalPtr;	 localPtr != NULL;	 localPtr = localPtr->nextPtr) {	/*	 * Check to see if this local is affected by namespace or	 * interp resolvers.  The resolver to use is cached for the	 * next invocation of the procedure.	 */	if (!(localPtr->flags & (VAR_ARGUMENT|VAR_TEMPORARY|VAR_RESOLVED))		&& (nsPtr->compiledVarResProc || iPtr->resolverPtr)) {	    resPtr = iPtr->resolverPtr;	    if (nsPtr->compiledVarResProc) {		result = (*nsPtr->compiledVarResProc)(nsPtr->interp,			localPtr->name, localPtr->nameLength,			(Tcl_Namespace *) nsPtr, &vinfo);	    } else {		result = TCL_CONTINUE;	    }	    while ((result == TCL_CONTINUE) && resPtr) {		if (resPtr->compiledVarResProc) {		    result = (*resPtr->compiledVarResProc)(nsPtr->interp,			    localPtr->name, localPtr->nameLength,			    (Tcl_Namespace *) nsPtr, &vinfo);		}		resPtr = resPtr->nextPtr;	    }	    if (result == TCL_OK) {		localPtr->resolveInfo = vinfo;		localPtr->flags |= VAR_RESOLVED;	    }	}	/*	 * Now invoke the resolvers to determine the exact variables that	 * should be used.	 */        resVarInfo = localPtr->resolveInfo;        resolvedVarPtr = NULL;        if (resVarInfo && resVarInfo->fetchProc) {            resolvedVarPtr = (Var*) (*resVarInfo->fetchProc)(interp,		    resVarInfo);        }        if (resolvedVarPtr) {	    varPtr->name = localPtr->name; /* will be just '\0' if temp var */	    varPtr->nsPtr = NULL;	    varPtr->hPtr = NULL;	    varPtr->refCount = 0;	    varPtr->tracePtr = NULL;	    varPtr->searchPtr = NULL;	    varPtr->flags = 0;            TclSetVarLink(varPtr);            varPtr->value.linkPtr = resolvedVarPtr;            resolvedVarPtr->refCount++;        } else {	    varPtr->value.objPtr = NULL;	    varPtr->name = localPtr->name; /* will be just '\0' if temp var */	    varPtr->nsPtr = NULL;	    varPtr->hPtr = NULL;	    varPtr->refCount = 0;	    varPtr->tracePtr = NULL;	    varPtr->searchPtr = NULL;	    varPtr->flags = localPtr->flags;        }	varPtr++;    }}/* *---------------------------------------------------------------------- * * TclExpandCodeArray -- * *	Procedure that uses malloc to allocate more storage for a *	CompileEnv's code array. * * Results: *	None.  * * Side effects: *	The byte code array in *envPtr is reallocated to a new array of *	double the size, and if envPtr->mallocedCodeArray is non-zero the *	old array is freed. Byte codes are copied from the old array to the *	new one. * *---------------------------------------------------------------------- */

⌨️ 快捷键说明

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