summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c174
1 files changed, 102 insertions, 72 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 17ad0bb..ed4fdd7 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -499,11 +499,11 @@ VarHashCreateVar(
*/
#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
- (((objPtr)->typePtr == &tclIntType) \
+ ((TclHasIntRep((objPtr), &tclIntType)) \
? (*(tPtr) = TCL_NUMBER_INT, \
*(ptrPtr) = (ClientData) \
(&((objPtr)->internalRep.wideValue)), TCL_OK) : \
- ((objPtr)->typePtr == &tclDoubleType) \
+ TclHasIntRep((objPtr), &tclDoubleType) \
? (((TclIsNaN((objPtr)->internalRep.doubleValue)) \
? (*(tPtr) = TCL_NUMBER_NAN) \
: (*(tPtr) = TCL_NUMBER_DOUBLE)), \
@@ -4768,7 +4768,7 @@ TEBCresume(
*/
if ((TclListObjGetElements(interp, valuePtr, &objc, &objv) == TCL_OK)
- && (value2Ptr->typePtr != &tclListType)
+ && !TclHasIntRep(value2Ptr, &tclListType)
&& (TclGetIntForIndexM(NULL, value2Ptr, objc-1,
&index) == TCL_OK)) {
TclDecrRefCount(value2Ptr);
@@ -5215,7 +5215,7 @@ TEBCresume(
objResultPtr = Tcl_NewStringObj((const char *)
valuePtr->bytes+index, 1);
} else {
- char buf[4];
+ char buf[4] = "";
int ch = Tcl_GetUniChar(valuePtr, index);
/*
@@ -5227,8 +5227,8 @@ TEBCresume(
objResultPtr = Tcl_NewObj();
} else {
length = Tcl_UniCharToUtf(ch, buf);
- if (!length) {
- length = Tcl_UniCharToUtf(-1, buf);
+ if ((ch >= 0xD800) && (length < 3)) {
+ length += Tcl_UniCharToUtf(-1, buf + length);
}
objResultPtr = Tcl_NewStringObj(buf, length);
}
@@ -5486,8 +5486,8 @@ TEBCresume(
* both.
*/
- if ((valuePtr->typePtr == &tclStringType)
- || (value2Ptr->typePtr == &tclStringType)) {
+ if (TclHasIntRep(valuePtr, &tclStringType)
+ || TclHasIntRep(value2Ptr, &tclStringType)) {
Tcl_UniChar *ustring1, *ustring2;
ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
@@ -5631,7 +5631,7 @@ TEBCresume(
/* [string is wideinteger] is WIDE_MIN to WIDE_MAX range */
Tcl_WideInt w;
- if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
+ if (TclGetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
type1 = TCL_NUMBER_INT;
}
}
@@ -6293,7 +6293,7 @@ TEBCresume(
case INST_TRY_CVT_TO_BOOLEAN:
valuePtr = OBJ_AT_TOS;
- if (valuePtr->typePtr == &tclBooleanType) {
+ if (TclHasIntRep(valuePtr, &tclBooleanType)) {
objResultPtr = TCONST(1);
} else {
int result = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK);
@@ -6769,55 +6769,23 @@ TEBCresume(
TRACE_APPEND(("OK\n"));
NEXT_INST_F(1, 1, 0);
- case INST_DICT_GET:
case INST_DICT_EXISTS: {
- register Tcl_Interp *interp2 = interp;
register int found;
opnd = TclGetUInt4AtPtr(pc+1);
TRACE(("%u => ", opnd));
dictPtr = OBJ_AT_DEPTH(opnd);
- if (*pc == INST_DICT_EXISTS) {
- interp2 = NULL;
- }
if (opnd > 1) {
- dictPtr = TclTraceDictPath(interp2, dictPtr, opnd-1,
- &OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ);
- if (dictPtr == NULL) {
- if (*pc == INST_DICT_EXISTS) {
- found = 0;
- goto afterDictExists;
- }
- TRACE_WITH_OBJ((
- "ERROR tracing dictionary path into \"%.30s\": ",
- O2S(OBJ_AT_DEPTH(opnd))),
- Tcl_GetObjResult(interp));
- goto gotError;
+ dictPtr = TclTraceDictPath(NULL, dictPtr, opnd-1,
+ &OBJ_AT_DEPTH(opnd-1), DICT_PATH_EXISTS);
+ if (dictPtr == NULL || dictPtr == DICT_PATH_NON_EXISTENT) {
+ found = 0;
+ goto afterDictExists;
}
}
- if (Tcl_DictObjGet(interp2, dictPtr, OBJ_AT_TOS,
+ if (Tcl_DictObjGet(NULL, dictPtr, OBJ_AT_TOS,
&objResultPtr) == TCL_OK) {
- if (*pc == INST_DICT_EXISTS) {
- found = (objResultPtr ? 1 : 0);
- goto afterDictExists;
- }
- if (!objResultPtr) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "key \"%s\" not known in dictionary",
- TclGetString(OBJ_AT_TOS)));
- DECACHE_STACK_INFO();
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
- TclGetString(OBJ_AT_TOS), NULL);
- CACHE_STACK_INFO();
- TRACE_ERROR(interp);
- goto gotError;
- }
- TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
- NEXT_INST_V(5, opnd+1, 1);
- } else if (*pc != INST_DICT_EXISTS) {
- TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s",
- O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
- goto gotError;
+ found = (objResultPtr ? 1 : 0);
} else {
found = 0;
}
@@ -6833,6 +6801,68 @@ TEBCresume(
JUMP_PEEPHOLE_V(found, 5, opnd+1);
}
+ case INST_DICT_GET:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ TRACE(("%u => ", opnd));
+ dictPtr = OBJ_AT_DEPTH(opnd);
+ if (opnd > 1) {
+ dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1,
+ &OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ);
+ if (dictPtr == NULL) {
+ TRACE_WITH_OBJ((
+ "ERROR tracing dictionary path into \"%.30s\": ",
+ O2S(OBJ_AT_DEPTH(opnd))),
+ Tcl_GetObjResult(interp));
+ goto gotError;
+ }
+ }
+ if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS,
+ &objResultPtr) != TCL_OK) {
+ TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s",
+ O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
+ goto gotError;
+ }
+ if (!objResultPtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "key \"%s\" not known in dictionary",
+ TclGetString(OBJ_AT_TOS)));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
+ TclGetString(OBJ_AT_TOS), NULL);
+ CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ NEXT_INST_V(5, opnd+1, 1);
+ case INST_DICT_GET_DEF:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ TRACE(("%u => ", opnd));
+ dictPtr = OBJ_AT_DEPTH(opnd+1);
+ if (opnd > 1) {
+ dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1,
+ &OBJ_AT_DEPTH(opnd), DICT_PATH_EXISTS);
+ if (dictPtr == NULL) {
+ TRACE_WITH_OBJ((
+ "ERROR tracing dictionary path into \"%.30s\": ",
+ O2S(OBJ_AT_DEPTH(opnd+1))),
+ Tcl_GetObjResult(interp));
+ goto gotError;
+ } else if (dictPtr == DICT_PATH_NON_EXISTENT) {
+ goto dictGetDefUseDefault;
+ }
+ }
+ if (Tcl_DictObjGet(interp, dictPtr, OBJ_UNDER_TOS,
+ &objResultPtr) != TCL_OK) {
+ TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s",
+ O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
+ goto gotError;
+ } else if (!objResultPtr) {
+ dictGetDefUseDefault:
+ objResultPtr = OBJ_AT_TOS;
+ }
+ TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ NEXT_INST_V(5, opnd+2, 1);
case INST_DICT_SET:
case INST_DICT_UNSET:
@@ -7108,7 +7138,7 @@ TEBCresume(
}
varPtr = LOCAL(opnd);
if (varPtr->value.objPtr) {
- if (varPtr->value.objPtr->typePtr == &dictIteratorType) {
+ if (TclHasIntRep(varPtr->value.objPtr, &dictIteratorType)) {
Tcl_Panic("mis-issued dictFirst!");
}
TclDecrRefCount(varPtr->value.objPtr);
@@ -7985,8 +8015,8 @@ ExecuteExtendedBinaryMathOp(
if (((wQuotient < (Tcl_WideInt) 0)
|| ((wQuotient == (Tcl_WideInt) 0)
- && ((w1 < (Tcl_WideInt)0 && w2 > (Tcl_WideInt)0)
- || (w1 > (Tcl_WideInt)0 && w2 < (Tcl_WideInt)0))))
+ && ((w1 < 0 && w2 > 0)
+ || (w1 > 0 && w2 < 0))))
&& (wQuotient * w2 != w1)) {
wQuotient -= (Tcl_WideInt) 1;
}
@@ -8020,7 +8050,7 @@ ExecuteExtendedBinaryMathOp(
mp_init(&bigResult);
mp_init(&bigRemainder);
mp_div(&big1, &big2, &bigResult, &bigRemainder);
- if (!mp_iszero(&bigRemainder) && (bigRemainder.sign != big2.sign)) {
+ if ((bigRemainder.used != 0) && (bigRemainder.sign != big2.sign)) {
/*
* Convert to Tcl's integer division rules.
*/
@@ -8042,11 +8072,11 @@ ExecuteExtendedBinaryMathOp(
switch (type2) {
case TCL_NUMBER_INT:
- invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0);
+ invalid = (*((const Tcl_WideInt *)ptr2) < 0);
break;
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
- invalid = mp_isneg(&big2);
+ invalid = big2.sign != MP_ZPOS;
mp_clear(&big2);
break;
default:
@@ -8063,7 +8093,7 @@ ExecuteExtendedBinaryMathOp(
* Zero shifted any number of bits is still zero.
*/
- if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == (Tcl_WideInt)0)) {
+ if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == 0)) {
return constants[0];
}
@@ -8121,11 +8151,11 @@ ExecuteExtendedBinaryMathOp(
switch (type1) {
case TCL_NUMBER_INT:
- zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0);
+ zero = (*(const Tcl_WideInt *)ptr1 > 0);
break;
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
- zero = (!mp_isneg(&big1));
+ zero = (big1.sign == MP_ZPOS);
mp_clear(&big1);
break;
default:
@@ -8146,7 +8176,7 @@ ExecuteExtendedBinaryMathOp(
if (type1 == TCL_NUMBER_INT) {
w1 = *(const Tcl_WideInt *)ptr1;
if ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideInt)) {
- if (w1 >= (Tcl_WideInt)0) {
+ if (w1 >= 0) {
return constants[0];
}
WIDE_RESULT(-1);
@@ -8249,9 +8279,9 @@ ExecuteExtendedBinaryMathOp(
oddExponent = (int) (w2 & (Tcl_WideInt)1);
} else {
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
- negativeExponent = mp_isneg(&big2);
+ negativeExponent = big2.sign != MP_ZPOS;
mp_mod_2d(&big2, 1, &big2);
- oddExponent = !mp_iszero(&big2);
+ oddExponent = big2.used != 0;
mp_clear(&big2);
}
@@ -8348,7 +8378,7 @@ ExecuteExtendedBinaryMathOp(
* Reduce small powers of 2 to shifts.
*/
- if ((Tcl_WideUInt)w2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){
+ if ((Tcl_WideUInt) w2 < CHAR_BIT * sizeof(Tcl_WideInt) - 1) {
WIDE_RESULT(signum * (((Tcl_WideInt) 1) << (int) w2));
}
goto overflowExpon;
@@ -8399,18 +8429,18 @@ ExecuteExtendedBinaryMathOp(
}
overflowExpon:
- Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
- if (big2.used > 1) {
- mp_clear(&big2);
+
+ if ((TclGetWideIntFromObj(NULL, value2Ptr, &w2) != TCL_OK)
+ || (value2Ptr->typePtr != &tclIntType)
+ || (Tcl_WideUInt)w2 >= (1<<28)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"exponent too large", -1));
return GENERAL_ARITHMETIC_ERROR;
}
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
mp_init(&bigResult);
- mp_expt_d_ex(&big1, big2.dp[0], &bigResult, 1);
+ mp_expt_d_ex(&big1, w2, &bigResult, 1);
mp_clear(&big1);
- mp_clear(&big2);
BIG_RESULT(&bigResult);
}
@@ -8568,7 +8598,7 @@ ExecuteExtendedBinaryMathOp(
mp_mul(&big1, &big2, &bigResult);
break;
case INST_DIV:
- if (mp_iszero(&big2)) {
+ if (big2.used == 0) {
mp_clear(&big1);
mp_clear(&big2);
mp_clear(&bigResult);
@@ -8577,7 +8607,7 @@ ExecuteExtendedBinaryMathOp(
mp_init(&bigRemainder);
mp_div(&big1, &big2, &bigResult, &bigRemainder);
/* TODO: internals intrusion */
- if (!mp_iszero(&bigRemainder)
+ if ((bigRemainder.used != 0)
&& (bigRemainder.sign != big2.sign)) {
/*
* Convert to Tcl's integer division rules.
@@ -8724,7 +8754,7 @@ TclCompareTwoNumbers(
goto wideCompare;
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
- if (mp_isneg(&big2)) {
+ if (big2.sign != MP_ZPOS) {
compare = MP_GT;
} else {
compare = MP_LT;
@@ -8761,7 +8791,7 @@ TclCompareTwoNumbers(
}
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
if ((d1 < (double)WIDE_MAX) && (d1 > (double)WIDE_MIN)) {
- if (mp_isneg(&big2)) {
+ if (big2.sign != MP_ZPOS) {
compare = MP_GT;
} else {
compare = MP_LT;
@@ -9622,7 +9652,7 @@ EvalStatsCmd(
for (i = 0; i < globalTablePtr->numBuckets; i++) {
for (entryPtr = globalTablePtr->buckets[i]; entryPtr != NULL;
entryPtr = entryPtr->nextPtr) {
- if (entryPtr->objPtr->typePtr == &tclByteCodeType) {
+ if (TclHasIntRep(entryPtr->objPtr, &tclByteCodeType)) {
numByteCodeLits++;
}
(void) TclGetStringFromObj(entryPtr->objPtr, &length);