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

📄 tclexecute.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
	    }	    	case INST_JUMP_FALSE4:	    opnd = TclGetInt4AtPtr(pc+1);	    pcAdjustment = 5;	    goto doJumpFalse;	case INST_JUMP_FALSE1:	    opnd = TclGetInt1AtPtr(pc+1);	    pcAdjustment = 2;	    	    doJumpFalse:	    {		int b;				valuePtr = POP_OBJECT();		if (valuePtr->typePtr == &tclIntType) {		    b = (valuePtr->internalRep.longValue != 0);		} else if (valuePtr->typePtr == &tclDoubleType) {		    b = (valuePtr->internalRep.doubleValue != 0.0);		} else {		    result = Tcl_GetBooleanFromObj(interp, valuePtr, &b);		    if (result != TCL_OK) {			TRACE_WITH_OBJ(("%s %d => ERROR: ", opName[opCode],				opnd), Tcl_GetObjResult(interp));			Tcl_DecrRefCount(valuePtr);			goto checkForCatch;		    }		}		if (b) {		    TRACE(("%s %d => %.20s true\n", opName[opCode], opnd,		            O2S(valuePtr)));		    TclDecrRefCount(valuePtr);		    ADJUST_PC(pcAdjustment);		} else {		    TRACE(("%s %d => %.20s false, new pc %u\n",			    opName[opCode], opnd, O2S(valuePtr),			   (unsigned int)(pc + opnd - codePtr->codeStart)));		    TclDecrRefCount(valuePtr);		    ADJUST_PC(opnd);		}	    }	    	case INST_LOR:	case INST_LAND:	    {		/*		 * Operands must be boolean or numeric. No int->double		 * conversions are performed.		 */				int i1, i2;		int iResult;		char *s;		Tcl_ObjType *t1Ptr, *t2Ptr;				value2Ptr = POP_OBJECT();		valuePtr  = POP_OBJECT();		t1Ptr = valuePtr->typePtr;		t2Ptr = value2Ptr->typePtr;				if ((t1Ptr == &tclIntType) || (t1Ptr == &tclBooleanType)) {		    i1 = (valuePtr->internalRep.longValue != 0);		} else if (t1Ptr == &tclDoubleType) {		    i1 = (valuePtr->internalRep.doubleValue != 0.0);		} else {	/* FAILS IF NULL STRING REP */		    s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);		    if (TclLooksLikeInt(s)) {			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,				valuePtr, &i);			i1 = (i != 0);		    } else {			result = Tcl_GetBooleanFromObj((Tcl_Interp *) NULL,				valuePtr, &i1);			i1 = (i1 != 0);		    }		    if (result != TCL_OK) {			TRACE(("%s \"%.20s\" => ILLEGAL TYPE %s \n",			        opName[opCode], O2S(valuePtr),			        (t1Ptr? t1Ptr->name : "null")));			IllegalExprOperandType(interp, opCode, valuePtr);			Tcl_DecrRefCount(valuePtr);			Tcl_DecrRefCount(value2Ptr);			goto checkForCatch;		    }		}				if ((t2Ptr == &tclIntType) || (t2Ptr == &tclBooleanType)) {		    i2 = (value2Ptr->internalRep.longValue != 0);		} else if (t2Ptr == &tclDoubleType) {		    i2 = (value2Ptr->internalRep.doubleValue != 0.0);		} else {	/* FAILS IF NULL STRING REP */		    s = Tcl_GetStringFromObj(value2Ptr, (int *) NULL);		    if (TclLooksLikeInt(s)) {			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,				value2Ptr, &i);			i2 = (i != 0);		    } else {			result = Tcl_GetBooleanFromObj((Tcl_Interp *) NULL,				value2Ptr, &i2);			i2 = (i2 != 0);		    }		    if (result != TCL_OK) {			TRACE(("%s \"%.20s\" => ILLEGAL TYPE %s \n",			        opName[opCode], O2S(value2Ptr),			        (t2Ptr? t2Ptr->name : "null")));			IllegalExprOperandType(interp, opCode, value2Ptr);			Tcl_DecrRefCount(valuePtr);			Tcl_DecrRefCount(value2Ptr);			goto checkForCatch;		    }		}				/*		 * Reuse the valuePtr object already on stack if possible.		 */		if (opCode == INST_LOR) {		    iResult = (i1 || i2);		} else {		    iResult = (i1 && i2);		}		if (Tcl_IsShared(valuePtr)) {		    PUSH_OBJECT(Tcl_NewLongObj(iResult));		    TRACE(("%s %.20s %.20s => %d\n", opName[opCode],			   O2S(valuePtr), O2S(value2Ptr), iResult));		    TclDecrRefCount(valuePtr);		} else {	/* reuse the valuePtr object */		    TRACE(("%s %.20s %.20s => %d\n", 			   opName[opCode], /* NB: stack top is off by 1 */			   O2S(valuePtr), O2S(value2Ptr), iResult));		    Tcl_SetLongObj(valuePtr, iResult);		    ++stackTop; /* valuePtr now on stk top has right r.c. */		}		TclDecrRefCount(value2Ptr);	    }	    ADJUST_PC(1);	case INST_EQ:	case INST_NEQ:	case INST_LT:	case INST_GT:	case INST_LE:	case INST_GE:	    {		/*		 * Any type is allowed but the two operands must have the	         * same type. We will compute value op value2.		 */		Tcl_ObjType *t1Ptr, *t2Ptr;		char *s1 = NULL;   /* Init. avoids compiler warning. */		char *s2 = NULL;   /* Init. avoids compiler warning. */		long i2 = 0;	   /* Init. avoids compiler warning. */		double d1 = 0.0;   /* Init. avoids compiler warning. */		double d2 = 0.0;   /* Init. avoids compiler warning. */		long iResult = 0;  /* Init. avoids compiler warning. */		value2Ptr = POP_OBJECT();		valuePtr  = POP_OBJECT();		t1Ptr = valuePtr->typePtr;		t2Ptr = value2Ptr->typePtr;				if ((t1Ptr != &tclIntType) && (t1Ptr != &tclDoubleType)) {		    s1 = Tcl_GetStringFromObj(valuePtr, &length);		    if (TclLooksLikeInt(s1)) { /* FAILS IF NULLS */			(void) Tcl_GetLongFromObj((Tcl_Interp *) NULL,				valuePtr, &i);		    } else {			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,				valuePtr, &d1);		    }		    t1Ptr = valuePtr->typePtr;		}		if ((t2Ptr != &tclIntType) && (t2Ptr != &tclDoubleType)) {		    s2 = Tcl_GetStringFromObj(value2Ptr, &length);		    if (TclLooksLikeInt(s2)) { /* FAILS IF NULLS */			(void) Tcl_GetLongFromObj((Tcl_Interp *) NULL,				value2Ptr, &i2);		    } else {			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,				value2Ptr, &d2);		    }		    t2Ptr = value2Ptr->typePtr;		}		if (((t1Ptr != &tclIntType) && (t1Ptr != &tclDoubleType))		        || ((t2Ptr != &tclIntType) && (t2Ptr != &tclDoubleType))) {		    /*		     * One operand is not numeric. Compare as strings.		     * THIS FAILS IF AN OBJECT'S STRING REP CONTAINS NULLS.		     */		    int cmpValue;		    s1 = TclGetStringFromObj(valuePtr, &length);		    s2 = TclGetStringFromObj(value2Ptr, &length);		    cmpValue = strcmp(s1, s2);		    switch (opCode) {		    case INST_EQ:			iResult = (cmpValue == 0);			break;		    case INST_NEQ:			iResult = (cmpValue != 0);			break;		    case INST_LT:			iResult = (cmpValue < 0);			break;		    case INST_GT:			iResult = (cmpValue > 0);			break;		    case INST_LE:			iResult = (cmpValue <= 0);			break;		    case INST_GE:			iResult = (cmpValue >= 0);			break;		    }		} else if ((t1Ptr == &tclDoubleType)		        || (t2Ptr == &tclDoubleType)) {		    /*		     * Compare as doubles.		     */		    if (t1Ptr == &tclDoubleType) {			d1 = valuePtr->internalRep.doubleValue;			if (t2Ptr == &tclIntType) {			    d2 = value2Ptr->internalRep.longValue;			} else {			    d2 = value2Ptr->internalRep.doubleValue;			}		    } else {	/* t1Ptr is int, t2Ptr is double */			d1 = valuePtr->internalRep.longValue;			d2 = value2Ptr->internalRep.doubleValue;		    }		    switch (opCode) {		    case INST_EQ:			iResult = d1 == d2;			break;		    case INST_NEQ:			iResult = d1 != d2;			break;		    case INST_LT:			iResult = d1 < d2;			break;		    case INST_GT:			iResult = d1 > d2;			break;		    case INST_LE:			iResult = d1 <= d2;			break;		    case INST_GE:			iResult = d1 >= d2;			break;		    }		} else {		    /*		     * Compare as ints.		     */		    i  = valuePtr->internalRep.longValue;		    i2 = value2Ptr->internalRep.longValue;		    switch (opCode) {		    case INST_EQ:			iResult = i == i2;			break;		    case INST_NEQ:			iResult = i != i2;			break;		    case INST_LT:			iResult = i < i2;			break;		    case INST_GT:			iResult = i > i2;			break;		    case INST_LE:			iResult = i <= i2;			break;		    case INST_GE:			iResult = i >= i2;			break;		    }		}		/*		 * Reuse the valuePtr object already on stack if possible.		 */				if (Tcl_IsShared(valuePtr)) {		    PUSH_OBJECT(Tcl_NewLongObj(iResult));		    TRACE(("%s %.20s %.20s => %ld\n", opName[opCode],		        O2S(valuePtr), O2S(value2Ptr), iResult));		    TclDecrRefCount(valuePtr);		} else {	/* reuse the valuePtr object */		    TRACE(("%s %.20s %.20s => %ld\n",			opName[opCode], /* NB: stack top is off by 1 */		        O2S(valuePtr), O2S(value2Ptr), iResult));		    Tcl_SetLongObj(valuePtr, iResult);		    ++stackTop; /* valuePtr now on stk top has right r.c. */		}		TclDecrRefCount(value2Ptr);	    }	    ADJUST_PC(1);	    	case INST_MOD:	case INST_LSHIFT:	case INST_RSHIFT:	case INST_BITOR:	case INST_BITXOR:	case INST_BITAND:	    {		/*		 * Only integers are allowed. We compute value op value2.		 */		long i2, rem, negative;		long iResult = 0; /* Init. avoids compiler warning. */				value2Ptr = POP_OBJECT();		valuePtr  = POP_OBJECT(); 		if (valuePtr->typePtr == &tclIntType) {		    i = valuePtr->internalRep.longValue;		} else {	/* try to convert to int */		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,			    valuePtr, &i);		    if (result != TCL_OK) {			TRACE(("%s %.20s %.20s => ILLEGAL 1st TYPE %s\n",			      opName[opCode], O2S(valuePtr), O2S(value2Ptr),			      (valuePtr->typePtr?				   valuePtr->typePtr->name : "null")));			IllegalExprOperandType(interp, opCode, valuePtr);			Tcl_DecrRefCount(valuePtr);			Tcl_DecrRefCount(value2Ptr);			goto checkForCatch;		    }		}		if (value2Ptr->typePtr == &tclIntType) {		    i2 = value2Ptr->internalRep.longValue;		} else {		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,			    value2Ptr, &i2);		    if (result != TCL_OK) {			TRACE(("%s %.20s %.20s => ILLEGAL 2nd TYPE %s\n",			      opName[opCode], O2S(valuePtr), O2S(value2Ptr),			      (value2Ptr->typePtr?				   value2Ptr->typePtr->name : "null")));			IllegalExprOperandType(interp, opCode, value2Ptr);			Tcl_DecrRefCount(valuePtr);			Tcl_DecrRefCount(value2Ptr);			goto checkForCatch;		    }		}		switch (opCode) {		case INST_MOD:		    /*		     * This code is tricky: C doesn't guarantee much about		     * the quotient or remainder, but Tcl does. The		     * remainder always has the same sign as the divisor and		     * a smaller absolute value.		     */		    if (i2 == 0) {			TRACE(("mod %ld %ld => DIVIDE BY ZERO\n", i, i2));			Tcl_DecrRefCount(valuePtr);			Tcl_DecrRefCount(value2Ptr);			goto divideByZero;		    }		    negative = 0;		    if (i2 < 0) {			i2 = -i2;			i = -i;			negative = 1;		    }		    rem  = i % i2;		    if (rem < 0) {			rem += i2;		    }		    if (negative) {			rem = -rem;		    }		    iResult = rem;		    break;		case INST_LSHIFT:		    iResult = i << i2;		    break;		case INST_RSHIFT:		    /*		     * The following code is a bit tricky: it ensures that		     * right shifts propagate the sign bit even on machines		     * where ">>" won't do it by default.		     */		    if (i < 0) {			iResult = ~((~i) >> i2);		    } else {			iResult = i >> i2;		    }		    break;		case INST_BITOR:		    iResult = i | i2;		    break;		case INST_BITXOR:		    iResult = i ^ i2;		    break;		case INST_BITAND:		    iResult = i & i2;		    break;		}		/*		 * Reuse the valuePtr object already on stack if possible.		 */				if (Tcl_IsShared(valuePtr)) {		    PUSH_OBJECT(Tcl_NewLongObj(iResult));		    TRACE(("%s %ld %ld => %ld\n", opName[opCode], i, i2,			   iResult));		    TclDecrRefCount(valuePtr);		} else {	/* reuse the valuePtr object */		    TRACE(("%s %ld %ld => %ld\n", opName[opCode], i, i2,		        iResult)); /* NB: stack top is off by 1 */		    Tcl_SetLongObj(valuePtr, iResult);		    ++stackTop; /* valuePtr now on stk top has right r.c. */		}		TclDecrRefCount(value2Ptr);	    }	    ADJUST_PC(1);	    	case INST_ADD:	case INST_SUB:	case INST_MULT:	case INST_DIV:	    {		/*		 * Operands must be numeric and ints get converted t

⌨️ 快捷键说明

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