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

📄 tclexecute.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tclExecute.c -- * *	This file contains procedures that execute byte-compiled Tcl *	commands. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclExecute.c 1.3 98/07/01 17:57:42 */#include "tclInt.h"#include "tclCompile.h"#ifdef NO_FLOAT_H#   include "../compat/float.h"#else#   include <float.h>#endif#ifndef TCL_NO_MATH#include "tclMath.h"#endif/* * The stuff below is a bit of a hack so that this file can be used * in environments that include no UNIX, i.e. no errno.  Just define * errno here. */#ifndef TCL_GENERIC_ONLY#include "tclPort.h"#else#define NO_ERRNO_H#endif#ifdef NO_ERRNO_Hint errno;#define EDOM 33#define ERANGE 34#endif/* * Boolean flag indicating whether the Tcl bytecode interpreter has been * initialized. */static int execInitialized = 0;/* * Variable that controls whether execution tracing is enabled and, if so, * what level of tracing is desired: *    0: no execution tracing *    1: trace invocations of Tcl procs only *    2: trace invocations of all (not compiled away) commands *    3: display each instruction executed * This variable is linked to the Tcl variable "tcl_traceExec". */int tclTraceExec = 0;/* * The following global variable is use to signal matherr that Tcl * is responsible for the arithmetic, so errors can be handled in a * fashion appropriate for Tcl.  Zero means no Tcl math is in * progress;  non-zero means Tcl is doing math. */int tcl_MathInProgress = 0;/* * The variable below serves no useful purpose except to generate * a reference to matherr, so that the Tcl version of matherr is * linked in rather than the system version. Without this reference * the need for matherr won't be discovered during linking until after * libtcl.a has been processed, so Tcl's version won't be used. */#ifdef NEED_MATHERRextern int matherr();int (*tclMatherrPtr)() = matherr;#endif/* * Array of instruction names. */static char *opName[256];/* * Mapping from expression instruction opcodes to strings; used for error * messages. Note that these entries must match the order and number of the * expression opcodes (e.g., INST_LOR) in tclCompile.h. */static char *operatorStrings[] = {    "||", "&&", "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>",    "+", "-", "*", "/", "%", "+", "-", "~", "!",    "BUILTIN FUNCTION", "FUNCTION"};    /* * Mapping from Tcl result codes to strings; used for error and debugging * messages.  */#ifdef TCL_COMPILE_DEBUGstatic char *resultStrings[] = {    "TCL_OK", "TCL_ERROR", "TCL_RETURN", "TCL_BREAK", "TCL_CONTINUE"};#endif /* TCL_COMPILE_DEBUG *//* * The following are statistics-related variables that record information * about the bytecode compiler and interpreter's operation. This includes * an array that records for each instruction how often it is executed. */#ifdef TCL_COMPILE_STATSstatic long numExecutions = 0;static int instructionCount[256];#endif /* TCL_COMPILE_STATS *//* * Macros for testing floating-point values for certain special cases. Test * for not-a-number by comparing a value against itself; test for infinity * by comparing against the largest floating-point value. */#define IS_NAN(v) ((v) != (v))#ifdef DBL_MAX#   define IS_INF(v) (((v) > DBL_MAX) || ((v) < -DBL_MAX))#else#   define IS_INF(v) 0#endif/* * Macro to adjust the program counter and restart the instruction execution * loop after each instruction is executed. */#define ADJUST_PC(instBytes) \    pc += instBytes;  continue/* * Macros used to cache often-referenced Tcl evaluation stack information * in local variables. Note that a DECACHE_STACK_INFO()-CACHE_STACK_INFO() * pair must surround any call inside TclExecuteByteCode (and a few other * procedures that use this scheme) that could result in a recursive call * to TclExecuteByteCode. */#define CACHE_STACK_INFO() \    stackPtr = eePtr->stackPtr; \    stackTop = eePtr->stackTop#define DECACHE_STACK_INFO() \    eePtr->stackTop = stackTop/* * Macros used to access items on the Tcl evaluation stack. PUSH_OBJECT * increments the object's ref count since it makes the stack have another * reference pointing to the object. However, POP_OBJECT does not decrement * the ref count. This is because the stack may hold the only reference to * the object, so the object would be destroyed if its ref count were * decremented before the caller had a chance to, e.g., store it in a * variable. It is the caller's responsibility to decrement the ref count * when it is finished with an object. */#define STK_ITEM(offset)    (stackPtr[stackTop + (offset)])#define STK_OBJECT(offset)  (STK_ITEM(offset).o)#define STK_INT(offset)     (STK_ITEM(offset).i)#define STK_POINTER(offset) (STK_ITEM(offset).p)/* * WARNING! It is essential that objPtr only appear once in the PUSH_OBJECT * macro. The actual parameter might be an expression with side effects, * and this ensures that it will be executed only once.  */    #define PUSH_OBJECT(objPtr) \    Tcl_IncrRefCount(stackPtr[++stackTop].o = (objPtr))    #define POP_OBJECT() \    (stackPtr[stackTop--].o)/* * Macros used to trace instruction execution. The macros TRACE, * TRACE_WITH_OBJ, and O2S are only used inside TclExecuteByteCode. * O2S is only used in TRACE* calls to get a string from an object. *  * NOTE THAT CLIENTS OF O2S ARE LIKELY TO FAIL IF THE OBJECT'S * STRING REP CONTAINS NULLS.  */#ifdef TCL_COMPILE_DEBUG	#define O2S(objPtr) \    Tcl_GetStringFromObj((objPtr), &length)	#ifdef TCL_COMPILE_STATS#define TRACE(a) \    if (traceInstructions) { \        fprintf(stdout, "%d: %d,%ld (%u) ", iPtr->numLevels, \	       stackTop, (tclObjsAlloced - tclObjsFreed), \	       (unsigned int)(pc - codePtr->codeStart)); \	printf a; \        fflush(stdout); \    }#define TRACE_WITH_OBJ(a, objPtr) \    if (traceInstructions) { \        fprintf(stdout, "%d: %d,%ld (%u) ", iPtr->numLevels, \	       stackTop, (tclObjsAlloced - tclObjsFreed), \	       (unsigned int)(pc - codePtr->codeStart)); \	printf a; \	bytes = Tcl_GetStringFromObj((objPtr), &length); \        TclPrintSource(stdout, bytes, TclMin(length, 30)); \        fprintf(stdout, "\n"); \        fflush(stdout); \    }#else  /* not TCL_COMPILE_STATS */#define TRACE(a) \    if (traceInstructions) { \        fprintf(stdout, "%d: %d (%u) ", iPtr->numLevels, stackTop, \	       (unsigned int)(pc - codePtr->codeStart)); \	printf a; \        fflush(stdout); \    }#define TRACE_WITH_OBJ(a, objPtr) \    if (traceInstructions) { \        fprintf(stdout, "%d: %d (%u) ", iPtr->numLevels, stackTop, \	       (unsigned int)(pc - codePtr->codeStart)); \	printf a; \	bytes = Tcl_GetStringFromObj((objPtr), &length); \        TclPrintSource(stdout, bytes, TclMin(length, 30)); \        fprintf(stdout, "\n"); \        fflush(stdout); \    }#endif /* TCL_COMPILE_STATS */#else  /* not TCL_COMPILE_DEBUG */	#define TRACE(a)#define TRACE_WITH_OBJ(a, objPtr)#define O2S(objPtr)	#endif /* TCL_COMPILE_DEBUG *//* * Declarations for local procedures to this file: */static void		CallTraceProcedure _ANSI_ARGS_((Tcl_Interp *interp,			    Trace *tracePtr, Command *cmdPtr,			    char *command, int numChars,			    int objc, Tcl_Obj *objv[]));static void		DupCmdNameInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr,			    Tcl_Obj *copyPtr));static int		ExprAbsFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprBinaryFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprCallMathFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, int objc, Tcl_Obj **objv));static int		ExprDoubleFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprIntFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprRandFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprRoundFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprSrandFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));static int		ExprUnaryFunc _ANSI_ARGS_((Tcl_Interp *interp,			    ExecEnv *eePtr, ClientData clientData));#ifdef TCL_COMPILE_STATSstatic int              EvalStatsCmd _ANSI_ARGS_((ClientData clientData,                            Tcl_Interp *interp, int argc, char **argv));#endif /* TCL_COMPILE_STATS */static void		FreeCmdNameInternalRep _ANSI_ARGS_((    			    Tcl_Obj *objPtr));static char *		GetSrcInfoForPc _ANSI_ARGS_((unsigned char *pc,        		    ByteCode* codePtr, int *lengthPtr));static void		GrowEvaluationStack _ANSI_ARGS_((ExecEnv *eePtr));static void		IllegalExprOperandType _ANSI_ARGS_((			    Tcl_Interp *interp, unsigned int opCode,			    Tcl_Obj *opndPtr));static void		InitByteCodeExecution _ANSI_ARGS_((			    Tcl_Interp *interp));static void		PrintByteCodeInfo _ANSI_ARGS_((ByteCode *codePtr));static void		RecordTracebackInfo _ANSI_ARGS_((Tcl_Interp *interp,			    unsigned char *pc, ByteCode *codePtr));static int		SetCmdNameFromAny _ANSI_ARGS_((Tcl_Interp *interp,			    Tcl_Obj *objPtr));#ifdef TCL_COMPILE_DEBUGstatic char *		StringForResultCode _ANSI_ARGS_((int result));#endif /* TCL_COMPILE_DEBUG */static void		UpdateStringOfCmdName _ANSI_ARGS_((Tcl_Obj *objPtr));#ifdef TCL_COMPILE_DEBUGstatic void		ValidatePcAndStackTop _ANSI_ARGS_((			    ByteCode *codePtr, unsigned char *pc,			    int stackTop, int stackLowerBound,			    int stackUpperBound));#endif /* TCL_COMPILE_DEBUG *//* * Table describing the built-in math functions. Entries in this table are * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's * operand byte. */BuiltinFunc builtinFuncTable[] = {#ifndef TCL_NO_MATH    {"acos", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) acos},    {"asin", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) asin},    {"atan", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) atan},    {"atan2", 2, {TCL_DOUBLE, TCL_DOUBLE}, ExprBinaryFunc, (ClientData) atan2},    {"ceil", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) ceil},    {"cos", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) cos},    {"cosh", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) cosh},    {"exp", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) exp},    {"floor", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) floor},    {"fmod", 2, {TCL_DOUBLE, TCL_DOUBLE}, ExprBinaryFunc, (ClientData) fmod},    {"hypot", 2, {TCL_DOUBLE, TCL_DOUBLE}, ExprBinaryFunc, (ClientData) hypot},    {"log", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) log},    {"log10", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) log10},    {"pow", 2, {TCL_DOUBLE, TCL_DOUBLE}, ExprBinaryFunc, (ClientData) pow},    {"sin", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) sin},    {"sinh", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) sinh},    {"sqrt", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) sqrt},    {"tan", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) tan},    {"tanh", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) tanh},#endif    {"abs", 1, {TCL_EITHER}, ExprAbsFunc, 0},    {"double", 1, {TCL_EITHER}, ExprDoubleFunc, 0},    {"int", 1, {TCL_EITHER}, ExprIntFunc, 0},    {"rand", 0, {TCL_EITHER}, ExprRandFunc, 0},	/* NOTE: rand takes no args. */    {"round", 1, {TCL_EITHER}, ExprRoundFunc, 0},    {"srand", 1, {TCL_INT}, ExprSrandFunc, 0},    {0},};/* * The structure below defines the command name Tcl object type by means of * procedures that can be invoked by generic object code. Objects of this * type cache the Command pointer that results from looking up command names * in the command hashtable. Such objects appear as the zeroth ("command * name") argument in a Tcl command. */Tcl_ObjType tclCmdNameType = {    "cmdName",				/* name */    FreeCmdNameInternalRep,		/* freeIntRepProc */    DupCmdNameInternalRep,		/* dupIntRepProc */    UpdateStringOfCmdName,		/* updateStringProc */    SetCmdNameFromAny			/* setFromAnyProc */};/* *---------------------------------------------------------------------- * * InitByteCodeExecution -- * *	This procedure is called once to initialize the Tcl bytecode *	interpreter. * * Results: *	None. * * Side effects: *	This procedure initializes the array of instruction names. If *	compiling with the TCL_COMPILE_STATS flag, it initializes the *	array that counts the executions of each instruction and it *	creates the "evalstats" command. It also registers the command name *	Tcl_ObjType. It also establishes the link between the Tcl *	"tcl_traceExec" and C "tclTraceExec" variables. * *---------------------------------------------------------------------- */static voidInitByteCodeExecution(interp)    Tcl_Interp *interp;		/* Interpreter for which the Tcl variable				 * "tcl_traceExec" is linked to control				 * instruction tracing. */{    int i;        Tcl_RegisterObjType(&tclCmdNameType);    (VOID *) memset(opName, 0, sizeof(opName));    for (i = 0;  instructionTable[i].name != NULL;  i++) {	opName[i] = instructionTable[i].name;    }#ifdef TCL_COMPILE_STATS        (VOID *) memset(instructionCount, 0, sizeof(instructionCount));    (VOID *) memset(tclByteCodeCount, 0, sizeof(tclByteCodeCount));    (VOID *) memset(tclSourceCount, 0, sizeof(tclSourceCount));    Tcl_CreateCommand(interp, "evalstats", EvalStatsCmd,		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);#endif /* TCL_COMPILE_STATS */        if (Tcl_LinkVar(interp, "tcl_traceExec", (char *) &tclTraceExec,		    TCL_LINK_INT) != TCL_OK) {	panic("InitByteCodeExecution: can't create link for tcl_traceExec variable");    }}/* *---------------------------------------------------------------------- * * TclCreateExecEnv -- * *	This procedure creates a new execution environment for Tcl bytecode *	execution. An ExecEnv points to a Tcl evaluation stack. An ExecEnv *	is typically created once for each Tcl interpreter (Interp *	structure) and recursively passed to TclExecuteByteCode to execute *	ByteCode sequences for nested commands. * * Results: *	A newly allocated ExecEnv is returned. This points to an empty *	evaluation stack of the standard initial size. * * Side effects: *	The bytecode interpreter is also initialized here, as this *	procedure will be called before any call to TclExecuteByteCode.

⌨️ 快捷键说明

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