浏览代码

Add workaround for issue #1292

James Urquhart 10 年之前
父节点
当前提交
d9436e65c5
共有 3 个文件被更改,包括 67 次插入29 次删除
  1. 36 11
      Engine/source/console/console.cpp
  2. 5 4
      Engine/source/console/console.h
  3. 26 14
      Engine/source/console/consoleInternal.cpp

+ 36 - 11
Engine/source/console/console.cpp

@@ -1736,12 +1736,34 @@ const char *ConsoleValue::getStringValue()
       return sval;
    else if (type == TypeInternalStringStackPtr)
       return STR.mBuffer + (uintptr_t)sval;
-   if(type == TypeInternalFloat)
-      return Con::getData(TypeF32, &fval, 0);
-   else if(type == TypeInternalInt)
-      return Con::getData(TypeS32, &ival, 0);
    else
-      return Con::getData(type, dataPtr, 0, enumTable);
+   {
+      // We need a string representation, so lets create one
+      const char *internalValue = NULL;
+
+      if(type == TypeInternalFloat)
+         internalValue = Con::getData(TypeF32, &fval, 0);
+      else if(type == TypeInternalInt)
+         internalValue = Con::getData(TypeS32, &ival, 0);
+      else
+         return Con::getData(type, dataPtr, 0, enumTable); // We can't save sval here since it is the same as dataPtr
+
+      if (!internalValue)
+         return "";
+
+      U32 stringLen = dStrlen(internalValue);
+      U32 newLen = ((stringLen + 1) + 15) & ~15; // pad upto next cache line
+	   
+      if (bufferLen == 0)
+         sval = (char *) dMalloc(newLen);
+      else if(newLen > bufferLen)
+         sval = (char *) dRealloc(sval, newLen);
+
+      dStrcpy(sval, internalValue);
+      bufferLen = newLen;
+
+      return sval;
+   }
 }
 
 StringStackPtr ConsoleValue::getStringStackPtr()
@@ -1777,11 +1799,13 @@ void ConsoleValue::setIntValue(U32 val)
    {
       fval = (F32)val;
       ival = val;
-      if(sval != typeValueEmpty)
+      if(bufferLen > 0)
       {
-         if (type != TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
-         sval = typeValueEmpty;
+         dFree(sval);
+         bufferLen = 0;
       }
+
+      sval = typeValueEmpty;
       type = TypeInternalInt;
    }
    else
@@ -1802,11 +1826,12 @@ void ConsoleValue::setFloatValue(F32 val)
    {
       fval = val;
       ival = static_cast<U32>(val);
-      if(sval != typeValueEmpty)
+      if(bufferLen > 0)
       {
-         if (type != TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
-         sval = typeValueEmpty;
+         dFree(sval);
+         bufferLen = 0;
       }
+      sval = typeValueEmpty;
       type = TypeInternalFloat;
    }
    else

+ 5 - 4
Engine/source/console/console.h

@@ -186,19 +186,20 @@ public:
       fval = 0;
       sval = typeValueEmpty;
       bufferLen = 0;
-	  type = TypeInternalString;
+      type = TypeInternalString;
    }
    
    void cleanup()
    {
-      if (type <= TypeInternalString &&
-          sval != typeValueEmpty && type != TypeInternalStackString && type != TypeInternalStringStackPtr)
+      if (bufferLen > 0)
+      {
          dFree(sval);
+         bufferLen = 0;
+      }
       sval = typeValueEmpty;
       type = ConsoleValue::TypeInternalString;
       ival = 0;
       fval = 0;
-      bufferLen = 0;
    }
 };
 

+ 26 - 14
Engine/source/console/consoleInternal.cpp

@@ -512,13 +512,17 @@ void ConsoleValue::setStringValue(const char * value)
 */
 	   if (value == typeValueEmpty)
       {
-            if (sval && sval != typeValueEmpty && type != TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
-            sval = typeValueEmpty;
+         if (bufferLen > 0)
+         {
+            dFree(sval);
             bufferLen = 0;
-            fval = 0.f;
-            ival = 0;
-            type = TypeInternalString;
-            return;
+         }
+
+         sval = typeValueEmpty;
+         fval = 0.f;
+         ival = 0;
+         type = TypeInternalString;
+         return;
       }
 
       U32 stringLen = dStrlen(value);
@@ -541,7 +545,7 @@ void ConsoleValue::setStringValue(const char * value)
       // may as well pad to the next cache line
       U32 newLen = ((stringLen + 1) + 15) & ~15;
 	  
-      if(sval == typeValueEmpty || type == TypeInternalStackString || type == TypeInternalStringStackPtr)
+      if(bufferLen == 0)
          sval = (char *) dMalloc(newLen);
       else if(newLen > bufferLen)
          sval = (char *) dRealloc(sval, newLen);
@@ -562,11 +566,16 @@ void ConsoleValue::setStackStringValue(const char *value)
 
    if(type <= ConsoleValue::TypeInternalString)
    {
+      // sval might still be temporarily present so we need to check and free it
+      if (bufferLen > 0)
+      {
+         dFree(sval);
+         bufferLen = 0;
+      }
+
 	   if (value == typeValueEmpty)
       {
-         if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString && type != ConsoleValue::TypeInternalStringStackPtr) dFree(sval);
          sval = typeValueEmpty;
-         bufferLen = 0;
          fval = 0.f;
          ival = 0;
          type = TypeInternalString;
@@ -587,7 +596,7 @@ void ConsoleValue::setStackStringValue(const char *value)
 
       type = TypeInternalStackString;
       sval = (char*)value;
-      bufferLen = stringLen;
+      bufferLen = 0;
    }
    else
       Con::setData(type, dataPtr, 0, 1, &value, enumTable);      
@@ -598,7 +607,11 @@ void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
    if(type <= ConsoleValue::TypeInternalString)
    {
       const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
-	   if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
+	   if (bufferLen > 0)
+      {
+         dFree(sval);
+         bufferLen = 0;
+      }
 
       U32 stringLen = dStrlen(value);
       if(stringLen < 256)
@@ -614,7 +627,7 @@ void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
 
       type = TypeInternalStringStackPtr;
       sval = (char*)(value - STR.mBuffer);
-      bufferLen = stringLen;
+      bufferLen = 0;
    }
    else
    {
@@ -680,8 +693,7 @@ Dictionary::Entry* Dictionary::addVariable(  const char *name,
    Entry *ent = add(StringTable->insert(name));
    
    if (  ent->value.type <= ConsoleValue::TypeInternalString &&
-         ent->value.sval != typeValueEmpty && 
-         ent->value.type != ConsoleValue::TypeInternalStackString && ent->value.type != ConsoleValue::TypeInternalStringStackPtr )
+         ent->value.bufferLen > 0 )
       dFree(ent->value.sval);
 
    ent->value.type = type;