Browse Source

Beginnings of the "pass everything using a native type wrapper" console code.

- ConsoleValue class is now the base value class.
- ConsoleValueRef is now used to supply function parameters. Values are disposable.
- Script functions return values instead of just strings where possible.
- Variables can be disposable strings
- Bytecode changed

Fix the issues with console method parameters and fields which prevented missions from loading.
James Urquhart 13 years ago
parent
commit
38c8e52c1d
68 changed files with 1508 additions and 526 deletions
  1. 5 3
      Engine/source/T3D/gameBase/gameConnection.cpp
  2. 6 3
      Engine/source/app/net/net.cpp
  3. 1 1
      Engine/source/app/net/tcpObject.cpp
  4. 1 1
      Engine/source/app/net/tcpObject.h
  5. 11 6
      Engine/source/cinterface/c_scripting.cpp
  6. 12 6
      Engine/source/cinterface/cinterface.cpp
  7. 5 3
      Engine/source/component/dynamicConsoleMethodComponent.cpp
  8. 2 2
      Engine/source/component/dynamicConsoleMethodComponent.h
  9. 1 1
      Engine/source/component/simComponent.cpp
  10. 1 1
      Engine/source/component/simComponent.h
  11. 1 1
      Engine/source/console/ICallMethod.h
  12. 1 1
      Engine/source/console/SimXMLDocument.cpp
  13. 1 1
      Engine/source/console/SimXMLDocument.h
  14. 62 11
      Engine/source/console/astNodes.cpp
  15. 4 2
      Engine/source/console/codeBlock.h
  16. 197 34
      Engine/source/console/compiledEval.cpp
  17. 7 2
      Engine/source/console/compiler.h
  18. 396 102
      Engine/source/console/console.cpp
  19. 200 31
      Engine/source/console/console.h
  20. 11 6
      Engine/source/console/consoleFunctions.cpp
  21. 160 48
      Engine/source/console/consoleInternal.cpp
  22. 47 98
      Engine/source/console/consoleInternal.h
  23. 1 1
      Engine/source/console/consoleLogger.cpp
  24. 1 1
      Engine/source/console/consoleLogger.h
  25. 69 64
      Engine/source/console/engineAPI.h
  26. 2 2
      Engine/source/console/engineDoc.cpp
  27. 5 5
      Engine/source/console/sim.cpp
  28. 21 23
      Engine/source/console/simEvents.cpp
  29. 6 3
      Engine/source/console/simEvents.h
  30. 1 1
      Engine/source/console/simObject.cpp
  31. 1 1
      Engine/source/console/simObject.h
  32. 1 1
      Engine/source/console/simObjectList.cpp
  33. 1 1
      Engine/source/console/simPersistSet.cpp
  34. 1 1
      Engine/source/console/simPersistSet.h
  35. 6 6
      Engine/source/console/simSet.cpp
  36. 2 2
      Engine/source/console/simSet.h
  37. 166 8
      Engine/source/console/stringStack.cpp
  38. 45 0
      Engine/source/console/stringStack.h
  39. 2 2
      Engine/source/core/fileObject.cpp
  40. 1 1
      Engine/source/environment/editors/guiMeshRoadEditorCtrl.cpp
  41. 1 1
      Engine/source/environment/editors/guiRiverEditorCtrl.cpp
  42. 1 1
      Engine/source/environment/editors/guiRoadEditorCtrl.cpp
  43. 1 1
      Engine/source/environment/waterObject.cpp
  44. 1 1
      Engine/source/environment/waterObject.h
  45. 1 1
      Engine/source/gui/controls/guiMaterialCtrl.cpp
  46. 1 1
      Engine/source/gui/controls/guiTreeViewCtrl.cpp
  47. 1 1
      Engine/source/gui/core/guiControl.cpp
  48. 1 1
      Engine/source/gui/core/guiControl.h
  49. 2 3
      Engine/source/gui/editor/guiFilterCtrl.cpp
  50. 1 1
      Engine/source/gui/editor/inspector/variableInspector.cpp
  51. 1 1
      Engine/source/gui/worldEditor/creator.cpp
  52. 2 2
      Engine/source/gui/worldEditor/editorIconRegistry.cpp
  53. 2 2
      Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp
  54. 2 2
      Engine/source/gui/worldEditor/terrainEditor.cpp
  55. 2 2
      Engine/source/gui/worldEditor/worldEditor.cpp
  56. 1 1
      Engine/source/gui/worldEditor/worldEditor.h
  57. 2 2
      Engine/source/materials/materialManager.cpp
  58. 1 1
      Engine/source/sfx/sfxSource.cpp
  59. 1 1
      Engine/source/sfx/sfxSource.h
  60. 1 1
      Engine/source/sfx/sfxTrack.cpp
  61. 1 1
      Engine/source/sfx/sfxTrack.h
  62. 5 2
      Engine/source/sim/actionMap.cpp
  63. 3 0
      Engine/source/sim/netConnection.cpp
  64. 2 2
      Engine/source/terrain/terrExport.cpp
  65. 1 1
      Engine/source/ts/collada/colladaImport.cpp
  66. 1 1
      Engine/source/ts/collada/colladaLights.cpp
  67. 4 4
      Engine/source/util/settings.cpp
  68. 1 1
      Engine/source/util/undo.cpp

+ 5 - 3
Engine/source/T3D/gameBase/gameConnection.cpp

@@ -269,7 +269,8 @@ ConsoleMethod(GameConnection, setConnectArgs, void, 3, 17,
    
    "@see GameConnection::onConnect()\n\n")
 {
-   object->setConnectArgs(argc - 2, argv + 2);
+   StringStackWrapper args(argc - 2, argv + 2);
+   object->setConnectArgs(args.count(), args);
 }
 
 void GameConnection::onTimedOut()
@@ -430,7 +431,7 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
       *errorString = "CR_INVALID_ARGS";
       return false;
    }
-   const char *connectArgv[MaxConnectArgs + 3];
+   ConsoleValueRef connectArgv[MaxConnectArgs + 3];
    for(U32 i = 0; i < mConnectArgc; i++)
    {
       char argString[256];
@@ -439,6 +440,7 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
       connectArgv[i + 3] = mConnectArgv[i];
    }
    connectArgv[0] = "onConnectRequest";
+   connectArgv[1] = NULL;
    char buffer[256];
    Net::addressToString(getNetAddress(), buffer);
    connectArgv[2] = buffer;
@@ -944,7 +946,7 @@ bool GameConnection::readDemoStartBlock(BitStream *stream)
 
 void GameConnection::demoPlaybackComplete()
 {
-   static const char *demoPlaybackArgv[1] = { "demoPlaybackComplete" };
+   static ConsoleValueRef demoPlaybackArgv[1] = { "demoPlaybackComplete" };
    Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(1, demoPlaybackArgv, false));
    Parent::demoPlaybackComplete();
 }

+ 6 - 3
Engine/source/app/net/net.cpp

@@ -237,7 +237,9 @@ ConsoleFunction( commandToServer, void, 2, RemoteCommandEvent::MaxRemoteCommandA
    NetConnection *conn = NetConnection::getConnectionToServer();
    if(!conn)
       return;
-   sendRemoteCommand(conn, argc - 1, argv + 1);
+
+   StringStackWrapper args(argc - 1, argv + 1);
+   sendRemoteCommand(conn, args.count(), args);
 }
 
 ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandArgs + 2, "(NetConnection client, string func, ...)"
@@ -274,7 +276,8 @@ ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandA
    NetConnection *conn;
    if(!Sim::findObject(argv[1], conn))
       return;
-   sendRemoteCommand(conn, argc - 2, argv + 2);
+   StringStackWrapper args(argc - 2, argv + 2);
+   sendRemoteCommand(conn, args.count(), args);
 }
 
 
@@ -288,7 +291,7 @@ ConsoleFunction(removeTaggedString, void, 2, 2, "(int tag)"
    "@see getTaggedString()\n"
    "@ingroup Networking\n")
 {
-   gNetStringTable->removeString(dAtoi(argv[1]+1), true);
+   gNetStringTable->removeString(dAtoi(((const char*)argv[1])+1), true);
 }
 
 ConsoleFunction( addTaggedString, const char*, 2, 2, "(string str)"

+ 1 - 1
Engine/source/app/net/tcpObject.cpp

@@ -226,7 +226,7 @@ TCPObject::~TCPObject()
    }
 }
 
-bool TCPObject::processArguments(S32 argc, const char **argv)
+bool TCPObject::processArguments(S32 argc, ConsoleValueRef *argv)
 {
    if(argc == 0)
       return true;

+ 1 - 1
Engine/source/app/net/tcpObject.h

@@ -79,7 +79,7 @@ public:
    void disconnect();
    State getState() { return mState; }
 
-   bool processArguments(S32 argc, const char **argv);
+   bool processArguments(S32 argc, ConsoleValueRef *argv);
    void send(const U8 *buffer, U32 bufferLen);
    void addToTable(NetSocket newTag);
    void removeFromTable();

+ 11 - 6
Engine/source/cinterface/c_scripting.cpp

@@ -76,7 +76,7 @@ extern "C" {
       if (!entry)
          return "";
 
-      const char* argv[] = {"consoleExportXML", 0};
+      ConsoleValueRef argv[] = {"consoleExportXML"};
 
       return entry->cb.mStringCallbackFunc(NULL, 1, argv);      
    }
@@ -215,7 +215,8 @@ extern "C" {
             return "";
       }
 
-      return entry->cb.mStringCallbackFunc(o, argc, argv);      
+      StringStackConsoleWrapper args(argc, argv);
+      return entry->cb.mStringCallbackFunc(o, args.count(), args);
    }
 
    bool script_call_namespace_entry_bool(Namespace::Entry* entry, S32 argc, const char** argv)
@@ -233,7 +234,8 @@ extern "C" {
             return "";
       }
 
-      return entry->cb.mBoolCallbackFunc(o, argc, argv);      
+      StringStackConsoleWrapper args(argc, argv);
+      return entry->cb.mBoolCallbackFunc(o, args.count(), args);
    }
 
    S32 script_call_namespace_entry_int(Namespace::Entry* entry, S32 argc, const char** argv)
@@ -251,7 +253,8 @@ extern "C" {
             return 0;
       }
 
-      return entry->cb.mIntCallbackFunc(o, argc, argv);      
+      StringStackConsoleWrapper args(argc, argv);
+      return entry->cb.mIntCallbackFunc(o, args.count(), args);
    }
 
    F32 script_call_namespace_entry_float(Namespace::Entry* entry, S32 argc, const char** argv)
@@ -269,7 +272,8 @@ extern "C" {
             return 0.0f;
       }
 
-      return entry->cb.mFloatCallbackFunc(o, argc, argv);      
+      StringStackConsoleWrapper args(argc, argv);
+      return entry->cb.mFloatCallbackFunc(o, args.count(), args);
    }
 
 
@@ -288,7 +292,8 @@ extern "C" {
             return;
       }
 
-      entry->cb.mVoidCallbackFunc(o, argc, argv);      
+      StringStackConsoleWrapper args(argc, argv);
+      entry->cb.mVoidCallbackFunc(o, args.count(), args);
    }
 
    int script_simobject_get_id(SimObject* so)

+ 12 - 6
Engine/source/cinterface/cinterface.cpp

@@ -262,7 +262,8 @@ extern "C" {
 		if (!entry)
 			return;
 
-		entry->cb.mVoidCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		entry->cb.mVoidCallbackFunc(NULL, args.count(), args);
 	}
 
 	F32 torque_callfloatfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
@@ -273,7 +274,8 @@ extern "C" {
 		if (!entry)
 			return 0.0f;
 
-		return entry->cb.mFloatCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mFloatCallbackFunc(NULL, args.count(), args);
 	}
 
 	S32 torque_callintfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
@@ -284,7 +286,8 @@ extern "C" {
 		if (!entry)
 			return 0;
 
-		return entry->cb.mIntCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mIntCallbackFunc(NULL, args.count(), args);
 	}
 
 
@@ -295,7 +298,8 @@ extern "C" {
 		if (!entry)
 			return "";
 
-		return entry->cb.mStringCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mStringCallbackFunc(NULL, args.count(), args);
 	}
 
 	bool torque_callboolfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
@@ -305,7 +309,8 @@ extern "C" {
 		if (!entry)
 			return "";
 
-		return entry->cb.mBoolCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mBoolCallbackFunc(NULL, args.count(), args);
 	}
 
 
@@ -319,7 +324,8 @@ extern "C" {
 		if(!entry->mFunctionOffset)
 			return "";
 
-		const char* ret = entry->mCode->exec(entry->mFunctionOffset, StringTable->insert(name), entry->mNamespace, argc, argv, false, entry->mPackage);
+		StringStackConsoleWrapper args(argc, argv);
+		const char* ret = entry->mCode->exec(entry->mFunctionOffset, StringTable->insert(name), entry->mNamespace, args.count(), args, false, entry->mPackage);
 
 		if (!ret || !dStrlen(ret))
 			return "";

+ 5 - 3
Engine/source/component/dynamicConsoleMethodComponent.cpp

@@ -90,7 +90,9 @@ const char *DynamicConsoleMethodComponent::callMethod( S32 argc, const char* met
    argv[1] = methodName;
    argv[2] = methodName;
 
-   return callMethodArgList( argc , argv );
+   StringStackConsoleWrapper argsw(argc, argv);
+
+   return callMethodArgList( argsw.count() , argsw );
 }
 
 #ifdef TORQUE_DEBUG
@@ -117,7 +119,7 @@ void DynamicConsoleMethodComponent::injectMethodCall( const char* method )
 }
 #endif
 
-const char* DynamicConsoleMethodComponent::callMethodArgList( U32 argc, const char *argv[], bool callThis /* = true  */ )
+const char* DynamicConsoleMethodComponent::callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis /* = true  */ )
 {
 #ifdef TORQUE_DEBUG
    injectMethodCall( argv[0] );
@@ -128,7 +130,7 @@ const char* DynamicConsoleMethodComponent::callMethodArgList( U32 argc, const ch
 
 // Call all components that implement methodName giving them a chance to operate
 // Components are called in reverse order of addition
-const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, const char *argv[], bool callThis /* = true  */ )
+const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, ConsoleValueRef argv[], bool callThis /* = true  */ )
 {
    // Set Owner
    SimObject *pThis = dynamic_cast<SimObject *>( this );

+ 2 - 2
Engine/source/component/dynamicConsoleMethodComponent.h

@@ -62,7 +62,7 @@ protected:
    /// Internal callMethod : Actually does component notification and script method execution
    ///  @attention This method does some magic to the argc argv to make Con::execute act properly
    ///   as such it's internal and should not be exposed or used except by this class
-   virtual const char* _callMethod( U32 argc, const char *argv[], bool callThis = true );
+   virtual const char* _callMethod( U32 argc, ConsoleValueRef argv[], bool callThis = true );
 
 public:
 
@@ -75,7 +75,7 @@ public:
 #endif
 
    /// Call Method
-   virtual const char* callMethodArgList( U32 argc, const char *argv[], bool callThis = true );
+   virtual const char* callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis = true );
 
    /// Call Method format string
    const char* callMethod( S32 argc, const char* methodName, ... );

+ 1 - 1
Engine/source/component/simComponent.cpp

@@ -171,7 +171,7 @@ void SimComponent::onRemove()
 
 //////////////////////////////////////////////////////////////////////////
 
-bool SimComponent::processArguments(S32 argc, const char **argv)
+bool SimComponent::processArguments(S32 argc, ConsoleValueRef *argv)
 {
    for(S32 i = 0; i < argc; i++)
    {

+ 1 - 1
Engine/source/component/simComponent.h

@@ -150,7 +150,7 @@ public:
 
    static void initPersistFields();
 
-   virtual bool processArguments(S32 argc, const char **argv);
+   virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
    
    bool isEnabled() const { return mEnabled; }
    

+ 1 - 1
Engine/source/console/ICallMethod.h

@@ -27,7 +27,7 @@ class ICallMethod
 {
 public:
    virtual const char* callMethod( S32 argc, const char* methodName, ... ) = 0;
-   virtual const char* callMethodArgList( U32 argc, const char *argv[], bool callThis = true ) = 0;
+   virtual const char* callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis = true ) = 0;
 };
 
 #endif

+ 1 - 1
Engine/source/console/SimXMLDocument.cpp

@@ -158,7 +158,7 @@ SimXMLDocument::~SimXMLDocument()
 // -----------------------------------------------------------------------------
 // Included for completeness.
 // -----------------------------------------------------------------------------
-bool SimXMLDocument::processArguments(S32 argc, const char** argv)
+bool SimXMLDocument::processArguments(S32 argc, ConsoleValueRef *argv)
 {
    return argc == 0;
 }

+ 1 - 1
Engine/source/console/SimXMLDocument.h

@@ -57,7 +57,7 @@ class SimXMLDocument: public SimObject
       // tie in to the script language.  The .cc file has more in depth
       // comments on these.
       //-----------------------------------------------------------------------
-      bool processArguments(S32 argc, const char** argv);
+      bool processArguments(S32 argc, ConsoleValueRef *argv);
       bool onAdd();
       void onRemove();
       static void initPersistFields();

+ 62 - 11
Engine/source/console/astNodes.cpp

@@ -236,7 +236,14 @@ U32 ExprNode::compileStmt(U32 *codeStream, U32 ip, U32, U32)
 U32 ReturnStmtNode::precompileStmt(U32)
 {
    addBreakCount();
-   return 1 + (expr ? expr->precompile(TypeReqString) : 0);
+   U32 size = 0;
+   if (expr) {
+      TypeReq walkType = expr->getPreferredType();
+	  if (walkType == TypeReqNone) walkType = TypeReqString;
+      size = expr->precompile(walkType);
+   }
+
+   return 1 + size;
 }
 
 U32 ReturnStmtNode::compileStmt(U32 *codeStream, U32 ip, U32, U32)
@@ -246,8 +253,22 @@ U32 ReturnStmtNode::compileStmt(U32 *codeStream, U32 ip, U32, U32)
       codeStream[ip++] = OP_RETURN_VOID;
    else
    {
-      ip = expr->compile(codeStream, ip, TypeReqString);
-      codeStream[ip++] = OP_RETURN;
+      TypeReq walkType = expr->getPreferredType();
+	  if (walkType == TypeReqNone) walkType = TypeReqString;
+      ip = expr->compile(codeStream, ip, walkType);
+
+	  // Return the correct type
+	  switch (walkType) {
+	  case TypeReqUInt:
+		codeStream[ip++] = OP_RETURN_UINT;
+		break;
+	  case TypeReqFloat:
+		codeStream[ip++] = OP_RETURN_FLT;
+		break;
+	  default:
+		codeStream[ip++] = OP_RETURN;
+		break;
+	  }
    }
    return ip;
 }
@@ -1347,8 +1368,11 @@ U32 FuncCallExprNode::precompile(TypeReq type)
       size++;
    precompileIdent(funcName);
    precompileIdent(nameSpace);
-   for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext())
-      size += walk->precompile(TypeReqString) + 1;
+   for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext()) {
+      TypeReq walkType = walk->getPreferredType();
+	  if (walkType == TypeReqNone) walkType = TypeReqString;
+      size += walk->precompile(walkType) + 1;
+   }
    return size + 5;
 }
 
@@ -1357,8 +1381,20 @@ U32 FuncCallExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
    codeStream[ip++] = OP_PUSH_FRAME;
    for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext())
    {
-      ip = walk->compile(codeStream, ip, TypeReqString);
-      codeStream[ip++] = OP_PUSH;
+      TypeReq walkType = walk->getPreferredType();
+	  if (walkType == TypeReqNone) walkType = TypeReqString;
+      ip = walk->compile(codeStream, ip, walkType);
+	  switch (walk->getPreferredType()) {
+            case TypeReqFloat:
+               codeStream[ip++] = OP_PUSH_FLT;
+               break;
+            case TypeReqUInt:
+               codeStream[ip++] = OP_PUSH_UINT;
+               break;
+            default:
+               codeStream[ip++] = OP_PUSH;
+               break;
+	  }
    }
    if(callType == MethodCall || callType == ParentCall)
       codeStream[ip++] = OP_CALLFUNC;
@@ -1729,8 +1765,11 @@ U32 ObjectDeclNode::precompileSubObject(bool)
 
    U32 argSize = 0;
    precompileIdent(parentObject);
-   for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext())
-      argSize += exprWalk->precompile(TypeReqString) + 1;
+   for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext()) {
+      TypeReq walkType = exprWalk->getPreferredType();
+	  if (walkType == TypeReqNone) walkType = TypeReqString;
+      argSize += exprWalk->precompile(walkType) + 1;
+   }
    argSize += classNameExpr->precompile(TypeReqString) + 1;
 
    U32 nameSize = objectNameExpr->precompile(TypeReqString) + 1;
@@ -1775,8 +1814,20 @@ U32 ObjectDeclNode::compileSubObject(U32 *codeStream, U32 ip, bool root)
    codeStream[ip++] = OP_PUSH;
    for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext())
    {
-      ip = exprWalk->compile(codeStream, ip, TypeReqString);
-      codeStream[ip++] = OP_PUSH;
+      TypeReq walkType = exprWalk->getPreferredType();
+	  if (walkType == TypeReqNone) walkType = TypeReqString;
+      ip = exprWalk->compile(codeStream, ip, walkType);
+	  switch (exprWalk->getPreferredType()) {
+            case TypeReqFloat:
+               codeStream[ip++] = OP_PUSH_FLT;
+               break;
+            case TypeReqUInt:
+               codeStream[ip++] = OP_PUSH_UINT;
+               break;
+            default:
+               codeStream[ip++] = OP_PUSH;
+               break;
+	  }
    }
    codeStream[ip++] = OP_CREATE_OBJECT;
    codeStream[ip] = STEtoU32(parentObject, ip);

+ 4 - 2
Engine/source/console/codeBlock.h

@@ -27,6 +27,8 @@
 #include "console/consoleParser.h"
 
 class Stream;
+class ConsoleValue;
+class ConsoleValueRef;
 
 /// Core TorqueScript code management class.
 ///
@@ -146,8 +148,8 @@ public:
    /// -1 a new frame is created. If the index is out of range the
    /// top stack frame is used.
    /// @param packageName The code package name or null.
-   const char *exec(U32 offset, const char *fnName, Namespace *ns, U32 argc, 
-      const char **argv, bool noCalls, StringTableEntry packageName, 
+   ConsoleValueRef exec(U32 offset, const char *fnName, Namespace *ns, U32 argc, 
+      ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName,
       S32 setFrame = -1);
 };
 

+ 197 - 34
Engine/source/console/compiledEval.cpp

@@ -102,7 +102,11 @@ IterStackRecord iterStack[ MaxStackSize ];
 F64 floatStack[MaxStackSize];
 S64 intStack[MaxStackSize];
 
+
+
+
 StringStack STR;
+ConsoleValueStack CSTK;
 
 U32 _FLT = 0;     ///< Stack pointer for floatStack.
 U32 _UINT = 0;    ///< Stack pointer for intStack.
@@ -401,14 +405,15 @@ static void setFieldComponent( SimObject* object, StringTableEntry field, const
    }
 }
 
-const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
+ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
 {
 #ifdef TORQUE_DEBUG
    U32 stackStart = STR.mStartStackSize;
+   U32 consoleStackStart = CSTK.mStackPos;
 #endif
 
    static char traceBuffer[1024];
-   U32 i;
+   S32 i;
    
    U32 iterDepth = 0;
 
@@ -424,7 +429,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
       // assume this points into a function decl:
       U32 fnArgc = code[ip + 5];
       thisFunctionName = U32toSTE(code[ip]);
-      argc = getMin(argc-1, fnArgc); // argv[0] is func name
+      S32 wantedArgc = getMin(argc-1, fnArgc); // argv[0] is func name
       if(gEvalState.traceOn)
       {
          traceBuffer[0] = 0;
@@ -456,11 +461,22 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
       }
       gEvalState.pushFrame(thisFunctionName, thisNamespace);
       popFrame = true;
-      for(i = 0; i < argc; i++)
+
+      for(i = 0; i < wantedArgc; i++)
       {
          StringTableEntry var = U32toSTE(code[ip + i + 6]);
          gEvalState.setCurVarNameCreate(var);
-         gEvalState.setStringVariable(argv[i+1]);
+
+		 ConsoleValueRef ref = argv[i+1];
+
+		 if (argv[i+1].isString())
+			gEvalState.setStringVariable(argv[i+1]);
+		 else if (argv[i+1].isInt())
+			gEvalState.setIntVariable(argv[i+1]);
+		 else if (argv[i+1].isFloat())
+			gEvalState.setFloatVariable(argv[i+1]);
+		 else
+			gEvalState.setStringVariable(argv[i+1]);
       }
       ip = ip + fnArgc + 6;
       curFloatTable = functionFloats;
@@ -497,6 +513,11 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
       }
    }
 
+   // jamesu - reset the console stack frame which at this point will contain 
+   // either nothing or argv[] which we just copied
+   // NOTE: it might be better to do this when we are finished?
+   CSTK.resetFrame();
+
    // Grab the state of the telenet debugger here once
    // so that the push and pop frames are always balanced.
    const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected();
@@ -530,7 +551,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
    char nsDocBlockClass[nsDocLength];
 
    U32 callArgc;
-   const char **callArgv;
+   ConsoleValueRef *callArgv;
 
    static char curFieldArray[256];
    static char prevFieldArray[256];
@@ -543,6 +564,10 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
       Con::gCurrentRoot = this->modPath;
    }
    const char * val;
+   const char *retValue;
+
+    // note: anything returned is pushed to CSTK and will be invalidated on the next exec()
+   ConsoleValueRef returnValue;
 
    // The frame temp is used by the variable accessor ops (OP_SAVEFIELD_* and
    // OP_LOADFIELD_*) to store temporary values for the fields.
@@ -615,8 +640,8 @@ breakContinue:
             objectCreationStack[ objectCreationStackIndex++ ].failJump = failJump;
 
             // Get the constructor information off the stack.
-            STR.getArgcArgv(NULL, &callArgc, &callArgv);
-            const char* objectName = callArgv[ 2 ];
+            CSTK.getArgcArgv(NULL, &callArgc, &callArgv);
+            const char *objectName = callArgv[ 2 ];
 
             // Con::printf("Creating object...");
 
@@ -638,6 +663,7 @@ breakContinue:
                   Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare data block %s with a different class.", getFileLine(ip), objectName);
                   ip = failJump;
                   STR.popFrame();
+				  CSTK.popFrame();
                   break;
                }
 
@@ -650,18 +676,19 @@ breakContinue:
                // IF we aren't looking at a local/internal object, then check if 
                // this object already exists in the global space
 
-               SimObject *obj = Sim::findObject( objectName );
+               SimObject *obj = Sim::findObject( (const char*)objectName );
                if (obj /*&& !obj->isLocalName()*/)
                {
                   if ( isSingleton )
                   {
                      // Make sure we're not trying to change types
-                     if ( dStricmp( obj->getClassName(), callArgv[1] ) != 0 )
+                     if ( dStricmp( obj->getClassName(), (const char*)callArgv[1] ) != 0 )
                      {
                         Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s] with a different class [%s] - was [%s].",
-                           getFileLine(ip), objectName, callArgv[1], obj->getClassName());
+                           getFileLine(ip), objectName, (const char*)callArgv[1], obj->getClassName());
                         ip = failJump;
                         STR.popFrame();
+                        CSTK.popFrame();
                         break;
                      }
 
@@ -679,13 +706,29 @@ breakContinue:
                         // string stack and may get stomped if deleteObject triggers
                         // script execution.
                         
-                        const char* savedArgv[ StringStack::MaxArgs ];
-                        dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc );
+                        ConsoleValueRef savedArgv[ StringStack::MaxArgs ];
+                        for (int i=0; i<callArgc; i++) {
+                           savedArgv[i] = callArgv[i];
+                        }
+                        //dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc );
                         
+						// Prevent stack value corruption
+						CSTK.pushFrame();
+						STR.pushFrame();
+						// --
+
                         obj->deleteObject();
                         obj = NULL;
 
-                        dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc );
+						// Prevent stack value corruption
+						CSTK.popFrame();
+						STR.popFrame();
+						// --
+
+                        //dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc );
+                        for (int i=0; i<callArgc; i++) {
+                           callArgv[i] = savedArgv[i];
+                        }
                      }
                      else if( dStricmp( redefineBehavior, "renameNew" ) == 0 )
                      {
@@ -714,6 +757,7 @@ breakContinue:
                               getFileLine(ip), newName.c_str() );
                            ip = failJump;
                            STR.popFrame();
+						   CSTK.popFrame();
                            break;
                         }
                         else
@@ -725,6 +769,7 @@ breakContinue:
                            getFileLine(ip), objectName);
                         ip = failJump;
                         STR.popFrame();
+						CSTK.popFrame();
                         break;
                      }
                   }
@@ -732,16 +777,17 @@ breakContinue:
             }
 
             STR.popFrame();
+			CSTK.popFrame();
             
             if(!currentNewObject)
             {
                // Well, looks like we have to create a new object.
-               ConsoleObject *object = ConsoleObject::create(callArgv[1]);
+               ConsoleObject *object = ConsoleObject::create((const char*)callArgv[1]);
 
                // Deal with failure!
                if(!object)
                {
-                  Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), callArgv[1]);
+                  Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), (const char*)callArgv[1]);
                   ip = failJump;
                   break;
                }
@@ -757,7 +803,7 @@ breakContinue:
                   else
                   {
                      // They tried to make a non-datablock with a datablock keyword!
-                     Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), callArgv[1]);
+                     Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), (const char*)callArgv[1]);
                      // Clean up...
                      delete object;
                      ip = failJump;
@@ -771,7 +817,7 @@ breakContinue:
                // Deal with the case of a non-SimObject.
                if(!currentNewObject)
                {
-                  Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), callArgv[1]);
+                  Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), (const char*)callArgv[1]);
                   delete object;
                   ip = failJump;
                   break;
@@ -798,7 +844,7 @@ breakContinue:
                   else
                   {
                      if ( Con::gObjectCopyFailures == -1 )
-                        Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, callArgv[1]);
+                        Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, (const char*)callArgv[1]);
                      else
                         ++Con::gObjectCopyFailures;
 
@@ -821,15 +867,30 @@ breakContinue:
                   currentNewObject->setOriginalName( objectName );
                }
 
+			   // Prevent stack value corruption
+			   CSTK.pushFrame();
+			   STR.pushFrame();
+			   // --
+
                // Do the constructor parameters.
                if(!currentNewObject->processArguments(callArgc-3, callArgv+3))
                {
                   delete currentNewObject;
                   currentNewObject = NULL;
                   ip = failJump;
+
+                  // Prevent stack value corruption
+                  CSTK.popFrame();
+                  STR.popFrame();
+                  // --
                   break;
                }
 
+               // Prevent stack value corruption
+               CSTK.popFrame();
+               STR.popFrame();
+               // --
+
                // If it's not a datablock, allow people to modify bits of it.
                if(!isDataBlock)
                {
@@ -854,6 +915,11 @@ breakContinue:
 
             // Con::printf("Adding object %s", currentNewObject->getName());
 
+            // Prevent stack value corruption
+            CSTK.pushFrame();
+            STR.pushFrame();
+            // --
+
             // Make sure it wasn't already added, then add it.
             if(currentNewObject->isProperlyAdded() == false)
             {
@@ -877,6 +943,10 @@ breakContinue:
                   Con::warnf(ConsoleLogEntry::General, "%s: Register object failed for object %s of class %s.", getFileLine(ip), currentNewObject->getName(), currentNewObject->getClassName());
                   delete currentNewObject;
                   ip = failJump;
+                  // Prevent stack value corruption
+                  CSTK.popFrame();
+                  STR.popFrame();
+                  // --
                   break;
                }
             }
@@ -885,6 +955,8 @@ breakContinue:
             SimDataBlock *dataBlock = dynamic_cast<SimDataBlock *>(currentNewObject);
             static String errorStr;
 
+
+
             // If so, preload it.
             if(dataBlock && !dataBlock->preload(true, errorStr))
             {
@@ -892,6 +964,11 @@ breakContinue:
                            currentNewObject->getName(), errorStr.c_str());
                dataBlock->deleteObject();
                ip = failJump;
+			   
+               // Prevent stack value corruption
+               CSTK.popFrame();
+               STR.popFrame();
+               // --
                break;
             }
 
@@ -946,6 +1023,10 @@ breakContinue:
             else
                intStack[++_UINT] = currentNewObject->getId();
 
+			// Prevent stack value corruption
+			CSTK.popFrame();
+			STR.popFrame();
+			// --
             break;
          }
 
@@ -1028,6 +1109,29 @@ breakContinue:
       		// We're falling thru here on purpose.
             
          case OP_RETURN:
+			retValue = STR.getStringValue();
+
+            if( iterDepth > 0 )
+            {
+               // Clear iterator state.
+               while( iterDepth > 0 )
+               {
+                  iterStack[ -- _ITER ].mIsStringIter = false;
+                  -- iterDepth;
+               }
+
+               STR.rewind();
+               STR.setStringValue( retValue ); // Not nice but works.
+			   retValue = STR.getStringValue();
+            }
+
+			// Previously the return value was on the stack and would be returned using STR.getStringValue().
+			// Now though we need to wrap it in a ConsoleValueRef 
+			returnValue.value = CSTK.pushStackString(retValue);
+               
+            goto execFinished;
+
+         case OP_RETURN_FLT:
          
             if( iterDepth > 0 )
             {
@@ -1038,10 +1142,27 @@ breakContinue:
                   -- iterDepth;
                }
                
-               const char* returnValue = STR.getStringValue();
-               STR.rewind();
-               STR.setStringValue( returnValue ); // Not nice but works.
             }
+
+            returnValue.value = CSTK.pushFLT(floatStack[_FLT]);
+            _FLT--;
+               
+            goto execFinished;
+
+         case OP_RETURN_UINT:
+         
+            if( iterDepth > 0 )
+            {
+               // Clear iterator state.
+               while( iterDepth > 0 )
+               {
+                  iterStack[ -- _ITER ].mIsStringIter = false;
+                  -- iterDepth;
+               }
+            }
+
+			returnValue.value = CSTK.pushUINT(intStack[_UINT]);
+			_UINT--;
                
             goto execFinished;
             
@@ -1514,6 +1635,7 @@ breakContinue:
                   getFileLine(ip-4), fnNamespace ? fnNamespace : "",
                   fnNamespace ? "::" : "", fnName);
                STR.popFrame();
+			   CSTK.popFrame();
                break;
             }
             // Now fall through to OP_CALLFUNC...
@@ -1538,7 +1660,7 @@ breakContinue:
             U32 callType = code[ip+2];
 
             ip += 3;
-            STR.getArgcArgv(fnName, &callArgc, &callArgv);
+            CSTK.getArgcArgv(fnName, &callArgc, &callArgv);
 
             const char *componentReturnValue = "";
 
@@ -1555,14 +1677,15 @@ breakContinue:
             else if(callType == FuncCallExprNode::MethodCall)
             {
                saveObject = gEvalState.thisObject;
-               gEvalState.thisObject = Sim::findObject(callArgv[1]);
+               gEvalState.thisObject = Sim::findObject((const char*)callArgv[1]);
                if(!gEvalState.thisObject)
                {
                   // Go back to the previous saved object.
                   gEvalState.thisObject = saveObject;
 
-                  Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), callArgv[1], fnName);
+                  Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), (const char*)callArgv[1], fnName);
                   STR.popFrame();
+				  CSTK.popFrame();
                   break;
                }
                
@@ -1618,6 +1741,7 @@ breakContinue:
                   }
                }
                STR.popFrame();
+			   CSTK.popFrame();
 
                if( routingId == MethodOnComponent )
                   STR.setStringValue( componentReturnValue );
@@ -1628,12 +1752,30 @@ breakContinue:
             }
             if(nsEntry->mType == Namespace::Entry::ConsoleFunctionType)
             {
-               const char *ret = "";
+               ConsoleValueRef ret;
                if(nsEntry->mFunctionOffset)
                   ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
-               
-               STR.popFrame();
-               STR.setStringValue(ret);
+
+			   STR.popFrame();
+			   // Functions are assumed to return strings, so look ahead to see if we can skip the conversion
+			   if(code[ip] == OP_STR_TO_UINT)
+               {
+                  ip++;
+                  intStack[++_UINT] = (U32)((S32)ret);
+               }
+               else if(code[ip] == OP_STR_TO_FLT)
+               {
+                  ip++;
+                  floatStack[++_FLT] = (F32)ret;
+               }
+               else if(code[ip] == OP_STR_TO_NONE)
+                  ip++;
+               else
+                  STR.setStringValue((const char*)ret);
+			   
+			   // This will clear everything including returnValue
+			   CSTK.popFrame();
+			   STR.clearFunctionOffset();
             }
             else
             {
@@ -1654,6 +1796,7 @@ breakContinue:
                      callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs);
                   Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-4), nsEntry->mUsage);
                   STR.popFrame();
+				  CSTK.popFrame();
                }
                else
                {
@@ -1663,16 +1806,18 @@ breakContinue:
                      {
                         const char *ret = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
                         STR.popFrame();
+						CSTK.popFrame();
                         if(ret != STR.getStringValue())
                            STR.setStringValue(ret);
-                        else
-                           STR.setLen(dStrlen(ret));
+                        //else
+                        //   STR.setLen(dStrlen(ret));
                         break;
                      }
                      case Namespace::Entry::IntCallbackType:
                      {
                         S32 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
                         STR.popFrame();
+						CSTK.popFrame();
                         if(code[ip] == OP_STR_TO_UINT)
                         {
                            ip++;
@@ -1695,6 +1840,7 @@ breakContinue:
                      {
                         F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
                         STR.popFrame();
+						CSTK.popFrame();
                         if(code[ip] == OP_STR_TO_UINT)
                         {
                            ip++;
@@ -1719,12 +1865,14 @@ breakContinue:
                            Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-4), fnName, functionName);
                         
                         STR.popFrame();
+						CSTK.popFrame();
                         STR.setStringValue("");
                         break;
                      case Namespace::Entry::BoolCallbackType:
                      {
                         bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
                         STR.popFrame();
+						CSTK.popFrame();
                         if(code[ip] == OP_STR_TO_UINT)
                         {
                            ip++;
@@ -1778,11 +1926,24 @@ breakContinue:
             intStack[++_UINT] = STR.compare();
             break;
          case OP_PUSH:
-            STR.push();
+			STR.push();
+			//Con::printf("Pushing str: %s",STR.getPreviousStringValue());
+            CSTK.pushString(STR.getPreviousStringValue());
+            break;
+         case OP_PUSH_UINT:
+			//Con::printf("Pushing int: %i",(S32)intStack[_UINT]);
+            CSTK.pushUINT(intStack[_UINT]);
+			_UINT--;
+            break;
+         case OP_PUSH_FLT:
+			//Con::printf("Pushing float: %f",(F32)intStack[_UINT]);
+            CSTK.pushFLT(floatStack[_FLT]);
+			_FLT--;
             break;
 
          case OP_PUSH_FRAME:
             STR.pushFrame();
+			CSTK.pushFrame();
             break;
 
          case OP_ASSERT:
@@ -1961,8 +2122,9 @@ execFinished:
    if ( telDebuggerOn && setFrame < 0 )
       TelDebugger->popStackFrame();
 
-   if ( popFrame )
+   if ( popFrame ) {
       gEvalState.popFrame();
+   }
 
    if(argv)
    {
@@ -2012,7 +2174,8 @@ execFinished:
    AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
    AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
 #endif
-   return STR.getStringValue();
+
+   return returnValue;
 }
 
 //------------------------------------------------------------

+ 7 - 2
Engine/source/console/compiler.h

@@ -54,6 +54,9 @@ namespace Compiler
       OP_RETURN,
       // fixes a bug when not explicitly returning a value
       OP_RETURN_VOID,
+	  OP_RETURN_FLT,
+	  OP_RETURN_UINT,
+
       OP_CMPEQ,
       OP_CMPGR,
       OP_CMPGE,
@@ -136,8 +139,10 @@ namespace Compiler
       OP_TERMINATE_REWIND_STR,
       OP_COMPARE_STR,
 
-      OP_PUSH,
-      OP_PUSH_FRAME,
+      OP_PUSH,          // String
+	  OP_PUSH_UINT,      // Integer
+	  OP_PUSH_FLT,    // Float
+      OP_PUSH_FRAME,    // Frame
 
       OP_ASSERT,
       OP_BREAK,

+ 396 - 102
Engine/source/console/console.cpp

@@ -42,6 +42,7 @@
 
 
 extern StringStack STR;
+extern ConsoleValueStack CSTK;
 
 ConsoleDocFragment* ConsoleDocFragment::smFirst;
 ExprEvalState gEvalState;
@@ -709,10 +710,11 @@ void errorf(const char* fmt,...)
 
 //---------------------------------------------------------------------------
 
-void setVariable(const char *name, const char *value)
+bool getVariableObjectField(const char *name, SimObject **object, const char **field)
 {
    // get the field info from the object..
-   if(name[0] != '$' && dStrchr(name, '.') && !isFunction(name))
+   const char *dot = dStrchr(name, '.');
+   if(name[0] != '$' && dot)
    {
       S32 len = dStrlen(name);
       AssertFatal(len < sizeof(scratchBuffer)-1, "Sim::getVariable - name too long");
@@ -721,17 +723,17 @@ void setVariable(const char *name, const char *value)
       char * token = dStrtok(scratchBuffer, ".");
       SimObject * obj = Sim::findObject(token);
       if(!obj)
-         return;
+         return false;
 
       token = dStrtok(0, ".\0");
       if(!token)
-         return;
+         return false;
 
       while(token != NULL)
       {
          const char * val = obj->getDataField(StringTable->insert(token), 0);
          if(!val)
-            return;
+            return false;
 
          char *fieldToken = token;
          token = dStrtok(0, ".\0");
@@ -739,17 +741,71 @@ void setVariable(const char *name, const char *value)
          {
             obj = Sim::findObject(token);
             if(!obj)
-               return;
+               return false;
          }
          else
          {
-            obj->setDataField(StringTable->insert(fieldToken), 0, value);
+			*object = obj;
+			*field = fieldToken;
+			return true;
          }
       }
    }
 
+   return false;
+}
+
+Dictionary::Entry *getLocalVariableEntry(const char *name)
+{
+   name = prependPercent(name);
+   return gEvalState.getCurrentFrame().lookup(StringTable->insert(name));
+}
+
+Dictionary::Entry *getVariableEntry(const char *name)
+{
+   name = prependDollar(name);
+   return gEvalState.globalVars.lookup(StringTable->insert(name));
+}
+
+Dictionary::Entry *addVariableEntry(const char *name)
+{
+   name = prependDollar(name);
+   return gEvalState.globalVars.add(StringTable->insert(name));
+}
+
+Dictionary::Entry *getAddVariableEntry(const char *name)
+{
    name = prependDollar(name);
-   gEvalState.globalVars.setVariable(StringTable->insert(name), value);
+   StringTableEntry stName = StringTable->insert(name);
+   Dictionary::Entry *entry = gEvalState.globalVars.lookup(stName);
+   if (!entry) {
+	   entry = gEvalState.globalVars.add(stName);
+   }
+   return entry;
+}
+
+Dictionary::Entry *getAddLocalVariableEntry(const char *name)
+{
+   name = prependPercent(name);
+   StringTableEntry stName = StringTable->insert(name);
+   Dictionary::Entry *entry = gEvalState.getCurrentFrame().lookup(stName);
+   if (!entry) {
+	   entry = gEvalState.getCurrentFrame().add(stName);
+   }
+   return entry;
+}
+
+void setVariable(const char *name, const char *value)
+{
+   SimObject *obj = NULL;
+   const char *objField = NULL;
+
+   if (getVariableObjectField(name, &obj, &objField)) {
+	   obj->setDataField(StringTable->insert(objField), 0, value);
+   } else {
+      name = prependDollar(name);
+      gEvalState.globalVars.setVariable(StringTable->insert(name), value);
+   }
 }
 
 void setLocalVariable(const char *name, const char *value)
@@ -760,21 +816,48 @@ void setLocalVariable(const char *name, const char *value)
 
 void setBoolVariable(const char *varName, bool value)
 {
-   setVariable(varName, value ? "1" : "0");
+   SimObject *obj = NULL;
+   const char *objField = NULL;
+
+   if (getVariableObjectField(varName, &obj, &objField)) {
+	   obj->setDataField(StringTable->insert(objField), 0, value ? "1" : "0");
+   } else {
+      varName = prependDollar(varName);
+      Dictionary::Entry *entry = getAddVariableEntry(varName);
+	  entry->setStringValue(value ? "1" : "0");
+   }
 }
 
 void setIntVariable(const char *varName, S32 value)
 {
-   char scratchBuffer[32];
-   dSprintf(scratchBuffer, sizeof(scratchBuffer), "%d", value);
-   setVariable(varName, scratchBuffer);
+   SimObject *obj = NULL;
+   const char *objField = NULL;
+
+   if (getVariableObjectField(varName, &obj, &objField)) {
+	   char scratchBuffer[32];
+	   dSprintf(scratchBuffer, sizeof(scratchBuffer), "%d", value);
+	   obj->setDataField(StringTable->insert(objField), 0, scratchBuffer);
+   } else {
+      varName = prependDollar(varName);
+      Dictionary::Entry *entry = getAddVariableEntry(varName);
+      entry->setIntValue(value);
+   }
 }
 
 void setFloatVariable(const char *varName, F32 value)
 {
-   char scratchBuffer[32];
-   dSprintf(scratchBuffer, sizeof(scratchBuffer), "%g", value);
-   setVariable(varName, scratchBuffer);
+   SimObject *obj = NULL;
+   const char *objField = NULL;
+
+   if (getVariableObjectField(varName, &obj, &objField)) {
+	   char scratchBuffer[32];
+	   dSprintf(scratchBuffer, sizeof(scratchBuffer), "%g", value);
+	   obj->setDataField(StringTable->insert(objField), 0, scratchBuffer);
+   } else {
+      varName = prependDollar(varName);
+      Dictionary::Entry *entry = getAddVariableEntry(varName);
+	  entry->setFloatValue(value);
+   }
 }
 
 //---------------------------------------------------------------------------
@@ -825,13 +908,14 @@ void stripColorChars(char* line)
    }
 }
 
-const char *getVariable(const char *name)
+// 
+const char *getObjectTokenField(const char *name)
 {
-   // get the field info from the object..
-   if(name[0] != '$' && dStrchr(name, '.') && !isFunction(name))
+   const char *dot = dStrchr(name, '.');
+   if(name[0] != '$' && dot)
    {
       S32 len = dStrlen(name);
-      AssertFatal(len < sizeof(scratchBuffer)-1, "Sim::getVariable - name too long");
+      AssertFatal(len < sizeof(scratchBuffer)-1, "Sim::getVariable - object name too long");
       dMemcpy(scratchBuffer, name, len+1);
 
       char * token = dStrtok(scratchBuffer, ".");
@@ -861,8 +945,18 @@ const char *getVariable(const char *name)
       }
    }
 
-   name = prependDollar(name);
-   return gEvalState.globalVars.getVariable(StringTable->insert(name));
+   return NULL;
+}
+
+const char *getVariable(const char *name)
+{
+   const char *objField = getObjectTokenField(name);
+   if (objField) {
+      return objField;
+   } else {
+      Dictionary::Entry *entry = getVariableEntry(name);
+	  return entry ? entry->getStringValue() : "";
+   }
 }
 
 const char *getLocalVariable(const char *name)
@@ -874,20 +968,36 @@ const char *getLocalVariable(const char *name)
 
 bool getBoolVariable(const char *varName, bool def)
 {
-   const char *value = getVariable(varName);
-   return *value ? dAtob(value) : def;
+   const char *objField = getObjectTokenField(varName);
+   if (objField) {
+      return *objField ? dAtob(objField) : def;
+   } else {
+      Dictionary::Entry *entry = getVariableEntry(varName);
+	  objField = entry ? entry->getStringValue() : "";
+      return *objField ? dAtob(objField) : def;
+   }
 }
 
 S32 getIntVariable(const char *varName, S32 def)
 {
-   const char *value = getVariable(varName);
-   return *value ? dAtoi(value) : def;
+   const char *objField = getObjectTokenField(varName);
+   if (objField) {
+      return *objField ? dAtoi(objField) : def;
+   } else {
+      Dictionary::Entry *entry = getVariableEntry(varName);
+	  return entry ? entry->getIntValue() : def;
+   }
 }
 
 F32 getFloatVariable(const char *varName, F32 def)
 {
-   const char *value = getVariable(varName);
-   return *value ? dAtof(value) : def;
+   const char *objField = getObjectTokenField(varName);
+   if (objField) {
+      return *objField ? dAtof(objField) : def;
+   } else {
+      Dictionary::Entry *entry = getVariableEntry(varName);
+	  return entry ? entry->getFloatValue() : def;
+   }
 }
 
 //---------------------------------------------------------------------------
@@ -1032,7 +1142,7 @@ const char *evaluatef(const char* string, ...)
    return newCodeBlock->compileExec(NULL, buffer, false, 0);
 }
 
-const char *execute(S32 argc, const char *argv[])
+const char *execute(S32 argc, ConsoleValueRef argv[])
 {
 #ifdef TORQUE_MULTITHREAD
    if(isMainThread())
@@ -1048,6 +1158,7 @@ const char *execute(S32 argc, const char *argv[])
 
          // Clean up arg buffers, if any.
          STR.clearFunctionOffset();
+		 CSTK.resetFrame();
          return "";
       }
       return ent->execute(argc, argv, &gEvalState);
@@ -1064,10 +1175,16 @@ const char *execute(S32 argc, const char *argv[])
 #endif
 }
 
+const char *execute(S32 argc, const char *argv[])
+{
+   StringStackConsoleWrapper args(argc, argv);
+   return execute(args.count(), args);
+}
+
 //------------------------------------------------------------------------------
-const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
+const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
 {
-   static char idBuf[16];
+   //static char idBuf[16];
    if(argc < 2)
       return "";
 
@@ -1077,14 +1194,21 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
    if( !thisCallOnly )
    {
       ICallMethod *com = dynamic_cast<ICallMethod *>(object);
-      if(com)
+      if(com) {
+         STR.pushFrame();
+         CSTK.pushFrame();
          com->callMethodArgList(argc, argv, false);
+         STR.popFrame();
+         CSTK.popFrame();
+	  }
    }
 
    if(object->getNamespace())
    {
-      dSprintf(idBuf, sizeof(idBuf), "%d", object->getId());
-      argv[1] = idBuf;
+	  ConsoleValueRef internalArgv[StringStack::MaxArgs];
+
+	  U32 ident = object->getId();
+	  ConsoleValueRef oldIdent = argv[1];
 
       StringTableEntry funcName = StringTable->insert(argv[0]);
       Namespace::Entry *ent = object->getNamespace()->lookup(funcName);
@@ -1094,14 +1218,14 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
          //warnf(ConsoleLogEntry::Script, "%s: undefined for object '%s' - id %d", funcName, object->getName(), object->getId());
 
          // Clean up arg buffers, if any.
+		 //CSTK.
          STR.clearFunctionOffset();
+		 CSTK.resetFrame();
          return "";
       }
 
       // Twiddle %this argument
-      const char *oldArg1 = argv[1];
-      dSprintf(idBuf, sizeof(idBuf), "%d", object->getId());
-      argv[1] = idBuf;
+	  argv[1] = (S32)ident;
 
       SimObject *save = gEvalState.thisObject;
       gEvalState.thisObject = object;
@@ -1109,7 +1233,7 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
       gEvalState.thisObject = save;
 
       // Twiddle it back
-      argv[1] = oldArg1;
+      argv[1] = oldIdent;
 
       return ret;
    }
@@ -1117,82 +1241,54 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
    return "";
 }
 
-#define B( a ) const char* a = NULL
-#define A const char*
-inline const char*_executef(SimObject *obj, S32 checkArgc, S32 argc, 
-                            A a, B(b), B(c), B(d), B(e), B(f), B(g), B(h), B(i), B(j), B(k))
+const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
+{
+   StringStackConsoleWrapper args(argc, argv);
+   return execute(object, args.count(), args, thisCallOnly);
+}
+
+inline const char*_executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValueRef *argv)
 {
-#undef A
-#undef B
    const U32 maxArg = 12;
    AssertWarn(checkArgc == argc, "Incorrect arg count passed to Con::executef(SimObject*)");
    AssertFatal(argc <= maxArg - 1, "Too many args passed to Con::_executef(SimObject*). Please update the function to handle more.");
-   const char* argv[maxArg];
-   argv[0] = a;
-   argv[1] = a;
-   argv[2] = b;
-   argv[3] = c;
-   argv[4] = d;
-   argv[5] = e;
-   argv[6] = f;
-   argv[7] = g;
-   argv[8] = h;
-   argv[9] = i;
-   argv[10] = j;
-   argv[11] = k;
-   return execute(obj, argc+1, argv);
-}
-
-#define A const char*
+   return execute(obj, argc, argv); // jamesu - argc should == argc
+}
+
+#define A ConsoleValueRef
 #define OBJ SimObject* obj
-const char *executef(OBJ, A a)                                    { return _executef(obj, 1, 1, a); }
-const char *executef(OBJ, A a, A b)                               { return _executef(obj, 2, 2, a, b); }
-const char *executef(OBJ, A a, A b, A c)                          { return _executef(obj, 3, 3, a, b, c); }
-const char *executef(OBJ, A a, A b, A c, A d)                     { return _executef(obj, 4, 4, a, b, c, d); }
-const char *executef(OBJ, A a, A b, A c, A d, A e)                { return _executef(obj, 5, 5, a, b, c, d, e); }
-const char *executef(OBJ, A a, A b, A c, A d, A e, A f)           { return _executef(obj, 6, 6, a, b, c, d, e, f); }
-const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g)      { return _executef(obj, 7, 7, a, b, c, d, e, f, g); }
-const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h) { return _executef(obj, 8, 8, a, b, c, d, e, f, g, h); }
-const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i) { return _executef(obj, 9, 9, a, b, c, d, e, f, g, h, i); }
-const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { return _executef(obj,10,10, a, b, c, d, e, f, g, h, i, j); }
-const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j, A k) { return _executef(obj,11,11, a, b, c, d, e, f, g, h, i, j, k); }
-#undef A
+const char *executef(OBJ, A a)                                    { ConsoleValueRef params[] = {a,ConsoleValueRef()}; return _executef(obj, 2, 2, params); }
+const char *executef(OBJ, A a, A b)                               { ConsoleValueRef params[] = {a,ConsoleValueRef(),b}; return _executef(obj, 3, 3, params); }
+const char *executef(OBJ, A a, A b, A c)                          { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c}; return _executef(obj, 4, 4, params); }
+const char *executef(OBJ, A a, A b, A c, A d)                     { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d}; return _executef(obj, 5, 5, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e)                { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e}; return _executef(obj, 6, 6, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e, A f)           { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f}; return _executef(obj, 7, 7, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g)      { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g}; return _executef(obj, 8, 8, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h}; return _executef(obj, 9, 9, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i}; return _executef(obj, 10, 10, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i,j}; return _executef(obj, 11, 11, params); }
+const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j, A k) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i,j,k}; return _executef(obj, 12, 12, params); }
 
 //------------------------------------------------------------------------------
-#define B( a ) const char* a = NULL
-#define A const char*
-inline const char*_executef(S32 checkArgc, S32 argc, A a, B(b), B(c), B(d), B(e), B(f), B(g), B(h), B(i), B(j))
+inline const char*_executef(S32 checkArgc, S32 argc, ConsoleValueRef *argv)
 {
-#undef A
-#undef B
    const U32 maxArg = 10;
    AssertFatal(checkArgc == argc, "Incorrect arg count passed to Con::executef()");
    AssertFatal(argc <= maxArg, "Too many args passed to Con::_executef(). Please update the function to handle more.");
-   const char* argv[maxArg];
-   argv[0] = a;
-   argv[1] = b;
-   argv[2] = c;
-   argv[3] = d;
-   argv[4] = e;
-   argv[5] = f;
-   argv[6] = g;
-   argv[7] = h;
-   argv[8] = i;
-   argv[9] = j;
    return execute(argc, argv);
 }
    
-#define A const char*
-const char *executef(A a)                                    { return _executef(1, 1, a); }
-const char *executef(A a, A b)                               { return _executef(2, 2, a, b); }
-const char *executef(A a, A b, A c)                          { return _executef(3, 3, a, b, c); }
-const char *executef(A a, A b, A c, A d)                     { return _executef(4, 4, a, b, c, d); }
-const char *executef(A a, A b, A c, A d, A e)                { return _executef(5, 5, a, b, c, d, e); }
-const char *executef(A a, A b, A c, A d, A e, A f)           { return _executef(6, 6, a, b, c, d, e, f); }
-const char *executef(A a, A b, A c, A d, A e, A f, A g)      { return _executef(7, 7, a, b, c, d, e, f, g); }
-const char *executef(A a, A b, A c, A d, A e, A f, A g, A h) { return _executef(8, 8, a, b, c, d, e, f, g, h); }
-const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i) { return _executef(9, 9, a, b, c, d, e, f, g, h, i); }
-const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { return _executef(10,10,a, b, c, d, e, f, g, h, i, j); }
+#define A ConsoleValueRef
+const char *executef(A a)                                    { ConsoleValueRef params[] = {a}; return _executef(1, 1, params); }
+const char *executef(A a, A b)                               { ConsoleValueRef params[] = {a,b}; return _executef(2, 2, params); }
+const char *executef(A a, A b, A c)                          { ConsoleValueRef params[] = {a,b,c}; return _executef(3, 3, params); }
+const char *executef(A a, A b, A c, A d)                     { ConsoleValueRef params[] = {a,b,c,d}; return _executef(4, 4, params); }
+const char *executef(A a, A b, A c, A d, A e)                { ConsoleValueRef params[] = {a,b,c,d,e}; return _executef(5, 5, params); }
+const char *executef(A a, A b, A c, A d, A e, A f)           { ConsoleValueRef params[] = {a,b,c,d,e,f}; return _executef(1, 1, params); }
+const char *executef(A a, A b, A c, A d, A e, A f, A g)      { ConsoleValueRef params[] = {a,b,c,d,e,f,g}; return _executef(1, 1, params); }
+const char *executef(A a, A b, A c, A d, A e, A f, A g, A h) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h}; return _executef(1, 1, params); }
+const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h,i}; return _executef(1, 1, params); }
+const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h,i,j}; return _executef(1, 1, params); }
 #undef A
 
 
@@ -1389,10 +1485,10 @@ StringTableEntry getModNameFromPath(const char *path)
 void postConsoleInput( RawData data )
 {
    // Schedule this to happen at the next time event.
-   char *argv[2];
+   ConsoleValueRef argv[2];
    argv[0] = "eval";
-   argv[1] = ( char* ) data.data;
-   Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, const_cast<const char**>(argv), false));
+   argv[1] = ( const char* ) data.data;
+   Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, argv, false));
 }
 
 //------------------------------------------------------------------------------
@@ -1455,3 +1551,201 @@ DefineEngineFunction( logWarning, void, ( const char* message ),,
 {
    Con::warnf( "%s", message );
 }
+
+ConsoleValueRef::ConsoleValueRef(const ConsoleValueRef &ref)
+{
+	value = ref.value;
+	stringStackValue = ref.stringStackValue;
+}
+
+ConsoleValueRef::ConsoleValueRef(const char *newValue) : value(NULL)
+{
+   *this = newValue;
+}
+
+ConsoleValueRef::ConsoleValueRef(const String &newValue) : value(NULL)
+{
+   *this = (const char*)(newValue.utf8());
+}
+
+
+ConsoleValueRef::ConsoleValueRef(S32 newValue) : value(NULL)
+{
+   *this = newValue;
+}
+
+ConsoleValueRef::ConsoleValueRef(F32 newValue) : value(NULL)
+{
+   *this = newValue;
+}
+
+ConsoleValueRef::ConsoleValueRef(F64 newValue) : value(NULL)
+{
+   *this = newValue;
+}
+
+StringStackWrapper::StringStackWrapper(int targc, ConsoleValueRef targv[])
+{
+   argv = new const char*[targc];
+   argc = targc;
+
+   for (int i=0; i<targc; i++) {
+      argv[i] = dStrdup(targv[i]);
+   }
+}
+
+StringStackWrapper::~StringStackWrapper()
+{
+   for (int i=0; i<argc; i++) {
+      dFree(argv[i]);
+   }
+   delete[] argv;
+}
+
+
+StringStackConsoleWrapper::StringStackConsoleWrapper(int targc, const char** targ)
+{
+   argv = new ConsoleValueRef[targc];
+   argc = targc;
+
+   for (int i=0; i<targc; i++) {
+      argv[i] = ConsoleValueRef(targ[i]);
+   }
+}
+
+StringStackConsoleWrapper::~StringStackConsoleWrapper()
+{
+   for (int i=0; i<argc; i++) {
+      argv[i] = NULL;
+   }
+   delete[] argv;
+}
+
+
+
+   U32 ConsoleValue::getIntValue()
+   {
+      if(type <= TypeInternalString)
+         return ival;
+      else
+         return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
+   }
+   
+   F32 ConsoleValue::getFloatValue()
+   {
+      if(type <= TypeInternalString)
+         return fval;
+      else
+         return dAtof(Con::getData(type, dataPtr, 0, enumTable));
+   }
+   
+   const char *ConsoleValue::getStringValue()
+   {
+      if(type == TypeInternalString || type == TypeInternalStackString)
+         return 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);
+   }
+   
+   void ConsoleValue::setIntValue(U32 val)
+   {
+      if(type <= TypeInternalString)
+      {
+         fval = (F32)val;
+         ival = val;
+         if(sval != typeValueEmpty)
+         {
+            if (type != TypeInternalStackString) dFree(sval);
+            sval = typeValueEmpty;
+         }
+         type = TypeInternalInt;
+      }
+      else
+      {
+         const char *dptr = Con::getData(TypeS32, &val, 0);
+         Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
+      }
+   }
+   
+   void ConsoleValue::setFloatValue(F32 val)
+   {
+      if(type <= TypeInternalString)
+      {
+         fval = val;
+         ival = static_cast<U32>(val);
+         if(sval != typeValueEmpty)
+         {
+            if (type != TypeInternalStackString) dFree(sval);
+            sval = typeValueEmpty;
+         }
+         type = TypeInternalFloat;
+      }
+      else
+      {
+         const char *dptr = Con::getData(TypeF32, &val, 0);
+         Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
+      }
+   }
+
+
+   const char *ConsoleValueRef::getStringArgValue()
+   {
+      if (value) {
+         if (stringStackValue == NULL) {
+			 stringStackValue = Con::getStringArg(value->getStringValue());
+		 }
+         return stringStackValue;
+      } else {
+         return "";
+      }
+   }
+
+
+extern ConsoleValueStack CSTK;
+   
+ConsoleValueRef& ConsoleValueRef::operator=(const ConsoleValueRef &newValue)
+{
+   value = newValue.value;
+   stringStackValue = newValue.stringStackValue;
+   return *this;
+}
+
+ConsoleValueRef& ConsoleValueRef::operator=(const char *newValue)
+{
+   value = CSTK.pushStackString(newValue);
+   stringStackValue = NULL;
+   return *this;
+}
+
+ConsoleValueRef& ConsoleValueRef::operator=(S32 newValue)
+{
+   value = CSTK.pushUINT(newValue);
+   stringStackValue = NULL;
+   return *this;
+}
+
+ConsoleValueRef& ConsoleValueRef::operator=(F32 newValue)
+{
+   value = CSTK.pushFLT(newValue);
+   stringStackValue = NULL;
+   return *this;
+}
+
+ConsoleValueRef& ConsoleValueRef::operator=(F64 newValue)
+{
+   value = CSTK.pushFLT(newValue);
+   stringStackValue = NULL;
+   return *this;
+}
+
+namespace Con
+{
+	void resetStackFrame()
+	{
+		CSTK.resetFrame();
+	}
+}

+ 200 - 31
Engine/source/console/console.h

@@ -29,15 +29,18 @@
 #ifndef _BITSET_H_
    #include "core/bitSet.h"
 #endif
+#ifndef _REFBASE_H_
+   #include "core/util/refBase.h"
+#endif
 #include <stdarg.h>
 
+#include "core/util/str.h"
 #include "core/util/journal/journaledSignal.h"
 
 class SimObject;
 class Namespace;
 struct ConsoleFunctionHeader;
 
-
 class EngineEnumTable;
 typedef EngineEnumTable EnumTable;
 
@@ -110,6 +113,163 @@ struct ConsoleLogEntry
 };
 
 typedef const char *StringTableEntry;
+extern char *typeValueEmpty;
+
+class ConsoleValue
+{
+public:
+   
+   enum
+   {
+      TypeInternalInt = -4,
+      TypeInternalFloat = -3,
+	  TypeInternalStackString = -2,
+      TypeInternalString = -1,
+   };
+   
+   S32 type;
+   
+public:
+   
+   // NOTE: This is protected to ensure no one outside
+   // of this structure is messing with it.
+   
+#pragma warning( push )
+#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
+   
+   // An variable is either a real dynamic type or
+   // its one exposed from C++ using a data pointer.
+   //
+   // We use this nameless union and struct setup
+   // to optimize the memory usage.
+   union
+   {
+      struct
+      {
+         char *sval;
+         U32 ival;  // doubles as strlen when type is TypeInternalString
+         F32 fval;
+         U32 bufferLen;
+      };
+      
+      struct
+      {
+         /// The real data pointer.
+         void *dataPtr;
+         
+         /// The enum lookup table for enumerated types.
+         const EnumTable *enumTable;
+      };
+   };
+   
+   U32 getIntValue();
+   
+   F32 getFloatValue();
+   
+   const char *getStringValue();
+   
+   void setIntValue(U32 val);
+
+   void setFloatValue(F32 val);
+   
+   void setStringValue(const char *value);
+   void setStackStringValue(const char *value);
+   
+   void init()
+   {
+      ival = 0;
+      fval = 0;
+      sval = typeValueEmpty;
+      bufferLen = 0;
+   }
+   
+   void cleanup()
+   {
+      if (type <= TypeInternalString &&
+          sval != typeValueEmpty && type != TypeInternalStackString )
+         dFree(sval);
+      sval = typeValueEmpty;
+      type = ConsoleValue::TypeInternalString;
+      ival = 0;
+      fval = 0;
+      bufferLen = 0;
+   }
+};
+
+// Proxy class for console variables
+// Can point to existing console variables
+// or act like a free floating value
+class ConsoleValueRef {
+public:
+   ConsoleValue *value;
+   const char *stringStackValue;
+
+   ConsoleValueRef() : value(0), stringStackValue(0) { ; }
+   ~ConsoleValueRef() { ; }
+
+   ConsoleValueRef(const ConsoleValueRef &ref);
+   ConsoleValueRef(const char *value);
+   ConsoleValueRef(const String &ref);
+   ConsoleValueRef(S32 value);
+   ConsoleValueRef(F32 value);
+   ConsoleValueRef(F64 value);
+
+   const char *getStringValue() { return value ? value->getStringValue() : ""; }
+   const char *getStringArgValue();
+
+   inline S32 getIntValue() { return value ? value->getIntValue() : 0; }
+   inline F32 getFloatValue() { return value ? value->getFloatValue() : 0.0f; }
+   //inline F64 getDoubleValue() { return value ? value->getDoubleValue() : 0.0; }
+
+   inline operator const char*() { return getStringValue(); }
+   inline operator String() { return String(getStringValue()); }
+   inline operator S32() { return getIntValue(); }
+   inline operator F32() { return getFloatValue(); }
+   //inline operator F64() { return getDoubleValue(); }
+
+   inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStackString : true; }
+   inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; }
+   inline bool isFloat() { return value ? value->type == ConsoleValue::TypeInternalFloat : false; }
+
+   // Note: operators replace value
+   ConsoleValueRef& operator=(const ConsoleValueRef &other);
+   ConsoleValueRef& operator=(const char *newValue);
+   ConsoleValueRef& operator=(S32 newValue);
+   ConsoleValueRef& operator=(F32 newValue);
+   ConsoleValueRef& operator=(F64 newValue);
+};
+
+// Transparently converts ConsoleValue[] to const char**
+class StringStackWrapper
+{
+public:
+   const char **argv;
+   int argc;
+
+   StringStackWrapper(int targc, ConsoleValueRef targv[]);
+   ~StringStackWrapper();
+
+   const char* operator[](int idx) { return argv[idx]; }
+   operator const char**() { return argv; }
+
+   int count() { return argc; }
+};
+
+// Transparently converts const char** to ConsoleValue
+class StringStackConsoleWrapper
+{
+public:
+   ConsoleValueRef *argv;
+   int argc;
+
+   StringStackConsoleWrapper(int targc, const char **targv);
+   ~StringStackConsoleWrapper();
+
+   ConsoleValueRef& operator[](int idx) { return argv[idx]; }
+   operator ConsoleValueRef*() { return argv; }
+
+   int count() { return argc; }
+};
 
 /// @defgroup console_callbacks Scripting Engine Callbacks
 ///
@@ -129,11 +289,11 @@ typedef const char *StringTableEntry;
 /// @{
 
 ///
-typedef const char * (*StringCallback)(SimObject *obj, S32 argc, const char *argv[]);
-typedef S32             (*IntCallback)(SimObject *obj, S32 argc, const char *argv[]);
-typedef F32           (*FloatCallback)(SimObject *obj, S32 argc, const char *argv[]);
-typedef void           (*VoidCallback)(SimObject *obj, S32 argc, const char *argv[]); // We have it return a value so things don't break..
-typedef bool           (*BoolCallback)(SimObject *obj, S32 argc, const char *argv[]);
+typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
+typedef S32             (*IntCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
+typedef F32           (*FloatCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
+typedef void           (*VoidCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); // We have it return a value so things don't break..
+typedef bool           (*BoolCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
 
 typedef void (*ConsumerCallback)(U32 level, const char *consoleLine);
 /// @}
@@ -182,7 +342,7 @@ namespace Con
       /// 09/12/07 - CAF - 43->44 remove newmsg operator
       /// 09/27/07 - RDB - 44->45 Patch from Andreas Kirsch: Added opcode to support correct void return
       /// 01/13/09 - TMS - 45->46 Added script assert
-      DSOVersion = 46,
+      DSOVersion = 47,
 
       MaxLineLength = 512,  ///< Maximum length of a line of console input.
       MaxDataTypes = 256    ///< Maximum number of registered data types.
@@ -415,6 +575,11 @@ namespace Con
    /// @return       The string value of the variable or "" if the variable does not exist.
    const char* getVariable(const char* name);
 
+   /// Retrieve the string value of an object field
+   /// @param name   "object.field" string to query
+   /// @return       The string value of the variable or NULL if no object is specified
+   const char* getObjectField(const char* name);
+
    /// Same as setVariable(), but for bools.
    void setBoolVariable (const char* name,bool var);
 
@@ -565,9 +730,11 @@ namespace Con
    /// char* result = execute(2, argv);
    /// @endcode
    const char *execute(S32 argc, const char* argv[]);
+   const char *execute(S32 argc, ConsoleValueRef argv[]);
 
    /// @see execute(S32 argc, const char* argv[])
-#define ARG const char*
+   // Note: this can't be ConsoleValueRef& since the compiler will confuse it with SimObject*
+#define ARG ConsoleValueRef
    const char *executef( ARG);
    const char *executef( ARG, ARG);
    const char *executef( ARG, ARG, ARG);
@@ -580,7 +747,6 @@ namespace Con
    const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
 #undef ARG
 
-
    /// Call a Torque Script member function of a SimObject from C/C++ code.
    /// @param object    Object on which to execute the method call.
    /// @param argc      Number of elements in the argv parameter (must be >2, see argv)
@@ -594,9 +760,10 @@ namespace Con
    /// char* result = execute(mysimobject, 3, argv);
    /// @endcode
    const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly = false);
+   const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false);
 
-   /// @see execute(SimObject *, S32 argc, const char *argv[])
-#define ARG const char*
+   /// @see execute(SimObject *, S32 argc, ConsoleValueRef argv[])
+#define ARG ConsoleValueRef
    const char *executef(SimObject *, ARG);
    const char *executef(SimObject *, ARG, ARG);
    const char *executef(SimObject *, ARG, ARG, ARG);
@@ -646,6 +813,8 @@ namespace Con
    char* getStringArg( const String& arg );
    /// @}
 
+   void resetStackFrame();
+
    /// @name Namespaces
    /// @{
 
@@ -941,14 +1110,14 @@ struct ConsoleDocFragment
       static ConsoleConstructor cfg_ConsoleFunctionGroup_##groupName##_GroupBegin(NULL,#groupName,usage)
 
 #  define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
-   returnType cf_##name(SimObject *, S32, const char **argv); \
+   returnType cf_##name(SimObject *, S32, ConsoleValueRef *argv); \
    ConsoleConstructor cc_##name##_obj(NULL,#name,cf_##name,usage1,minArgs,maxArgs); \
-      returnType cf_##name(SimObject *, S32 argc, const char **argv)
+      returnType cf_##name(SimObject *, S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \
-   returnType ctf_##name(SimObject *, S32, const char **argv); \
+   returnType ctf_##name(SimObject *, S32, ConsoleValueRef *argv); \
    ConsoleConstructor cc_##name##_obj(NULL,#name,ctf_##name,usage1,minArgs,maxArgs, true); \
-   returnType ctf_##name(SimObject *, S32 argc, const char **argv)
+   returnType ctf_##name(SimObject *, S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleFunctionGroupEnd(groupName) \
       static ConsoleConstructor cfg_##groupName##_GroupEnd(NULL,#groupName,NULL)
@@ -961,22 +1130,22 @@ struct ConsoleDocFragment
    static ConsoleConstructor cc_##className##_##groupName##_GroupBegin(#className,#groupName,usage)
 
 #  define ConsoleMethod(className,name,returnType,minArgs,maxArgs,usage1) \
-   inline returnType cm_##className##_##name(className *, S32, const char **argv); \
-   returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, const char **argv) { \
+   inline returnType cm_##className##_##name(className *, S32, ConsoleValueRef *argv); \
+   returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
          AssertFatal( dynamic_cast<className*>( object ), "Object passed to " #name " is not a " #className "!" ); \
          conmethod_return_##returnType ) cm_##className##_##name(static_cast<className*>(object),argc,argv); \
       };                                                                                              \
       ConsoleConstructor cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage1,minArgs,maxArgs); \
-      inline returnType cm_##className##_##name(className *object, S32 argc, const char **argv)
+      inline returnType cm_##className##_##name(className *object, S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleStaticMethod(className,name,returnType,minArgs,maxArgs,usage1) \
-   inline returnType cm_##className##_##name(S32, const char **); \
-   returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, const char **argv) { \
+   inline returnType cm_##className##_##name(S32, ConsoleValueRef *); \
+   returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
    conmethod_return_##returnType ) cm_##className##_##name(argc,argv); \
    }; \
    ConsoleConstructor \
    cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage1,minArgs,maxArgs); \
-   inline returnType cm_##className##_##name(S32 argc, const char **argv)
+   inline returnType cm_##className##_##name(S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleMethodGroupEnd(className, groupName) \
    static ConsoleConstructor cc_##className##_##groupName##_GroupEnd(#className,#groupName,NULL)
@@ -999,32 +1168,32 @@ struct ConsoleDocFragment
 
 // These are identical to what's above, we just want to null out the usage strings.
 #  define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1)                   \
-      static returnType c##name(SimObject *, S32, const char **);                   \
+      static returnType c##name(SimObject *, S32, ConsoleValueRef*);                   \
       static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs);\
-      static returnType c##name(SimObject *, S32 argc, const char **argv)
+      static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1)                   \
-   static returnType c##name(SimObject *, S32, const char **);                   \
+   static returnType c##name(SimObject *, S32, ConsoleValueRef*);                   \
    static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs, true);\
-   static returnType c##name(SimObject *, S32 argc, const char **argv)
+   static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleMethod(className,name,returnType,minArgs,maxArgs,usage1)                             \
-      static inline returnType c##className##name(className *, S32, const char **argv);               \
-      static returnType c##className##name##caster(SimObject *object, S32 argc, const char **argv) {  \
+      static inline returnType c##className##name(className *, S32, ConsoleValueRef *argv);               \
+      static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValueRef *argv) {  \
          conmethod_return_##returnType ) c##className##name(static_cast<className*>(object),argc,argv);              \
       };                                                                                              \
       static ConsoleConstructor                                                                       \
          className##name##obj(#className,#name,c##className##name##caster,"",minArgs,maxArgs);        \
-      static inline returnType c##className##name(className *object, S32 argc, const char **argv)
+      static inline returnType c##className##name(className *object, S32 argc, ConsoleValueRef *argv)
 
 #  define ConsoleStaticMethod(className,name,returnType,minArgs,maxArgs,usage1)                       \
-      static inline returnType c##className##name(S32, const char **);                                \
-      static returnType c##className##name##caster(SimObject *object, S32 argc, const char **argv) {  \
+      static inline returnType c##className##name(S32, ConsoleValueRef*);                                \
+      static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValueRef *argv) {  \
          conmethod_return_##returnType ) c##className##name(argc,argv);                                                        \
       };                                                                                              \
       static ConsoleConstructor                                                                       \
          className##name##obj(#className,#name,c##className##name##caster,"",minArgs,maxArgs);        \
-      static inline returnType c##className##name(S32 argc, const char **argv)
+      static inline returnType c##className##name(S32 argc, ConsoleValueRef *argv)
 
 #define ConsoleDoc( text )
 

+ 11 - 6
Engine/source/console/consoleFunctions.cpp

@@ -1207,7 +1207,9 @@ ConsoleFunction( nextToken, const char *, 4, 4, "( string str, string token, str
    "@endtsexample\n\n"
    "@ingroup Strings" )
 {
-   char *str = (char *) argv[1];
+   char buffer[4096];
+   dStrncpy(buffer, argv[1], 4096);
+   char *str = buffer;
    const char *token = argv[2];
    const char *delim = argv[3];
 
@@ -1240,7 +1242,9 @@ ConsoleFunction( nextToken, const char *, 4, 4, "( string str, string token, str
          str++;
    }
 
-   return str;
+   char *ret = Con::getReturnBuffer(dStrlen(str)+1);
+   dStrncpy(ret, str, dStrlen(str)+1);
+   return ret;
 }
 
 //=============================================================================
@@ -1302,16 +1306,17 @@ ConsoleFunction(getTag, const char *, 2, 2, "(string textTagString)"
    TORQUE_UNUSED(argc);
    if(argv[1][0] == StringTagPrefixByte)
    {
+	  const char *arg  = argv[1];
       const char * space = dStrchr(argv[1], ' ');
 
       U32 len;
       if(space)
-         len = space - argv[1];
+         len = space - arg;
       else
-         len = dStrlen(argv[1]) + 1;
+         len = dStrlen(arg) + 1;
 
       char * ret = Con::getReturnBuffer(len);
-      dStrncpy(ret, argv[1] + 1, len - 1);
+      dStrncpy(ret, arg + 1, len - 1);
       ret[len - 1] = 0;
 
       return(ret);
@@ -2394,7 +2399,7 @@ ConsoleFunction( pushInstantGroup, void, 1, 2, "([group])"
 				"@internal")
 {
    if( argc > 1 )
-      Con::pushInstantGroup( argv[ 1 ] );
+      Con::pushInstantGroup( (const char*)argv[ 1 ] );
    else
       Con::pushInstantGroup();
 }

+ 160 - 48
Engine/source/console/consoleInternal.cpp

@@ -35,6 +35,44 @@
 //#define DEBUG_SPEW
 
 
+Dictionary::Entry smLocalDictionaryEntryStack[4096*4];
+Dictionary::Entry *smLocalDictionaryEntryStackHead = NULL;
+
+void setupDictionaryStack()
+{
+   smLocalDictionaryEntryStackHead = &smLocalDictionaryEntryStack[0];
+   
+   for (int i=0; i<4096*4; i++) {
+      (smLocalDictionaryEntryStackHead + i)->mNext = i == (4096*4)-1 ? NULL : smLocalDictionaryEntryStackHead + (i+1);
+   }
+}
+
+Dictionary::Entry * getDictionaryStackEntry()
+{
+   Dictionary::Entry *entry = smLocalDictionaryEntryStackHead;
+   AssertFatal(entry, "No more local variables");
+   
+   entry->reset();
+   
+   Dictionary::Entry *next = entry->mNext;
+   
+   smLocalDictionaryEntryStackHead = next;
+   
+   entry->mNext = NULL;
+   
+   return entry;
+}
+
+void disposeDictionaryStackEntry(Dictionary::Entry *entry)
+{
+   Dictionary::Entry *prevHead = smLocalDictionaryEntryStackHead;
+   smLocalDictionaryEntryStackHead = entry;
+   
+   smLocalDictionaryEntryStackHead->mNext = prevHead;
+}
+
+
+
 #define ST_INIT_SIZE 15
 
 static char scratchBuffer[1024];
@@ -168,13 +206,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo
 
    for(s = sortList.begin(); s != sortList.end(); s++)
    {
-      switch((*s)->type)
+      switch((*s)->value.type)
       {
-         case Entry::TypeInternalInt:
-            dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat);
+         case ConsoleValue::TypeInternalInt:
+            dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.ival, cat);
             break;
-         case Entry::TypeInternalFloat:
-            dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat);
+         case ConsoleValue::TypeInternalFloat:
+            dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.fval, cat);
             break;
          default:
             expandEscape(expandBuffer, (*s)->getStringValue());
@@ -228,13 +266,13 @@ void Dictionary::exportVariables( const char *varString, Vector<String> *names,
 
       if ( values )
       {
-         switch ( (*s)->type )
+         switch ( (*s)->value.type )
          {
-         case Entry::TypeInternalInt:
-            values->push_back( String::ToString( (*s)->ival ) );         
+         case ConsoleValue::TypeInternalInt:
+            values->push_back( String::ToString( (*s)->value.ival ) );         
             break;
-         case Entry::TypeInternalFloat:
-            values->push_back( String::ToString( (*s)->fval ) );         
+         case ConsoleValue::TypeInternalFloat:
+            values->push_back( String::ToString( (*s)->value.fval ) );         
             break;
          default:         
             expandEscape( expandBuffer, (*s)->getStringValue() );
@@ -284,10 +322,13 @@ Dictionary::Entry *Dictionary::lookup(StringTableEntry name)
 Dictionary::Entry *Dictionary::add(StringTableEntry name)
 {
    // Try to find an existing match.
+   //printf("Add Variable %s\n", name);
    
    Entry* ret = lookup( name );
-   if( ret )
+   if( ret ) {
+      //printf("Found Variable %s (named %s)\n", name, ret->name);
       return ret;
+   }
    
    // Rehash if the table get's too crowded.  Be aware that this might
    // modify a table that we don't own.
@@ -296,6 +337,7 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name)
    if( hashTable->count > hashTable->size * 2 )
    {
       // Allocate a new table.
+      printf("Re-hashing dictionary...\n");
       
       const U32 newTableSize = hashTable->size * 4 - 1;
       Entry** newTableData = new Entry*[ newTableSize ];
@@ -307,7 +349,10 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name)
          for( Entry* entry = hashTable->data[ i ]; entry != NULL; )
          {
             Entry* next = entry->nextEntry;
-            S32 index = HashPointer( entry->name ) % newTableSize;
+            U32 index = HashPointer( entry->name ) % newTableSize;
+            
+            
+            //printf("  Variable(%s) in bucket %i moved to bucket %i\n", entry->name, i, index);
             
             entry->nextEntry = newTableData[ index ];
             newTableData[ index ] = entry;
@@ -328,9 +373,10 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name)
    
    // Add the new entry.
 
-   ret = hashTable->mChunker.alloc();
-   constructInPlace( ret, name );
-   S32 idx = HashPointer(name) % hashTable->size;
+   ret = getDictionaryStackEntry();//hashTable->mChunker.alloc();
+   ret->name = name;
+   //constructInPlace( ret, name );
+   U32 idx = HashPointer(name) % hashTable->size;
    ret->nextEntry = hashTable->data[idx];
    hashTable->data[idx] = ret;
    
@@ -350,8 +396,8 @@ void Dictionary::remove(Dictionary::Entry *ent)
 
    *walk = (ent->nextEntry);
 
-   destructInPlace( ent );
-   hashTable->mChunker.free( ent );
+   disposeDictionaryStackEntry( ent );
+   //hashTable->mChunker.free( ent );
 
    hashTable->count--;
 }
@@ -412,13 +458,13 @@ void Dictionary::reset()
       while( walk )
       {
          Entry* temp = walk->nextEntry;
-         destructInPlace( walk );
+         disposeDictionaryStackEntry( walk );
          walk = temp;
       }
    }
 
    dMemset( ownHashTable.data, 0, ownHashTable.size * sizeof( Entry* ) );
-   ownHashTable.mChunker.freeBlocks( true );
+   //ownHashTable.mChunker.freeBlocks( true );
    
    ownHashTable.count = 0;
    hashTable = NULL;
@@ -454,7 +500,7 @@ char *typeValueEmpty = "";
 Dictionary::Entry::Entry(StringTableEntry in_name)
 {
    name = in_name;
-   type = TypeInternalString;
+   value.type = ConsoleValue::TypeInternalString;
    notify = NULL;
    nextEntry = NULL;
    mUsage = NULL;
@@ -462,17 +508,12 @@ Dictionary::Entry::Entry(StringTableEntry in_name)
 
    // NOTE: This is data inside a nameless
    // union, so we don't need to init the rest.
-   ival = 0;
-   fval = 0;
-   sval = typeValueEmpty;
-   bufferLen = 0;
+   value.init();
 }
 
 Dictionary::Entry::~Entry()
 {
-   if (  type <= TypeInternalString &&
-         sval != typeValueEmpty )
-      dFree(sval);
+   value.cleanup();
 
    if ( notify )
       delete notify;
@@ -497,15 +538,11 @@ const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
    return "";
 }
 
-void Dictionary::Entry::setStringValue(const char * value)
+void ConsoleValue::setStringValue(const char * value)
 {
-   if( mIsConstant )
-   {
-      Con::errorf( "Cannot assign value to constant '%s'.", name );
-      return;
-   }
+   if (value == NULL) value = typeValueEmpty;
 
-   if(type <= TypeInternalString)
+   if(type <= ConsoleValue::TypeInternalString)
    {
       // Let's not remove empty-string-valued global vars from the dict.
       // If we remove them, then they won't be exported, and sometimes
@@ -519,6 +556,15 @@ void Dictionary::Entry::setStringValue(const char * value)
          return;
       }
 */
+	  if (value == typeValueEmpty) {
+		 if (sval && sval != typeValueEmpty && type != TypeInternalStackString) dFree(sval);
+		 sval = typeValueEmpty;
+		 bufferLen = 0;
+         fval = 0.f;
+         ival = 0;
+		 type = TypeInternalString;
+		 return;
+	  }
 
       U32 stringLen = dStrlen(value);
 
@@ -537,25 +583,89 @@ void Dictionary::Entry::setStringValue(const char * value)
          ival = 0;
       }
 
-      type = TypeInternalString;
-
       // may as well pad to the next cache line
       U32 newLen = ((stringLen + 1) + 15) & ~15;
-      
-      if(sval == typeValueEmpty)
+	  
+	  if(sval == typeValueEmpty || type == TypeInternalStackString)
          sval = (char *) dMalloc(newLen);
       else if(newLen > bufferLen)
          sval = (char *) dRealloc(sval, newLen);
 
+      type = TypeInternalString;
+
       bufferLen = newLen;
       dStrcpy(sval, value);
    }
    else
       Con::setData(type, dataPtr, 0, 1, &value, enumTable);      
+}
 
-   // Fire off the notification if we have one.
-   if ( notify )
-      notify->trigger();
+
+void ConsoleValue::setStackStringValue(const char * value)
+{
+   if (value == NULL) value = typeValueEmpty;
+
+   if(type <= ConsoleValue::TypeInternalString)
+   {
+	  if (value == typeValueEmpty) {
+		 if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString) dFree(sval);
+		 sval = typeValueEmpty;
+		 bufferLen = 0;
+         fval = 0.f;
+         ival = 0;
+		 type = TypeInternalString;
+		 return;
+	  }
+
+      U32 stringLen = dStrlen(value);
+      if(stringLen < 256)
+      {
+         fval = dAtof(value);
+         ival = dAtoi(value);
+      }
+      else
+      {
+         fval = 0.f;
+         ival = 0;
+      }
+
+      type = TypeInternalStackString;
+	  sval = (char*)value;
+      bufferLen = stringLen;
+   }
+   else
+      Con::setData(type, dataPtr, 0, 1, &value, enumTable);      
+}
+
+
+S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid)
+{
+    Entry *ent = lookup(name);
+    if(ent)
+    {
+        if(entValid)
+            *entValid = true;
+        return ent->getIntValue();
+    }
+    if(entValid)
+        *entValid = false;
+
+    return 0;
+}
+
+F32 Dictionary::getFloatVariable(StringTableEntry name, bool *entValid)
+{
+    Entry *ent = lookup(name);
+    if(ent)
+    {
+        if(entValid)
+            *entValid = true;
+        return ent->getFloatValue();
+    }
+    if(entValid)
+        *entValid = false;
+
+    return 0;
 }
 
 void Dictionary::setVariable(StringTableEntry name, const char *value)
@@ -582,19 +692,19 @@ Dictionary::Entry* Dictionary::addVariable(  const char *name,
 
    Entry *ent = add(StringTable->insert(name));
    
-   if (  ent->type <= Entry::TypeInternalString &&
-         ent->sval != typeValueEmpty )
-      dFree(ent->sval);
+   if (  ent->value.type <= ConsoleValue::TypeInternalString &&
+         ent->value.sval != typeValueEmpty && ent->value.type != ConsoleValue::TypeInternalStackString )
+      dFree(ent->value.sval);
 
-   ent->type = type;
-   ent->dataPtr = dataPtr;
+   ent->value.type = type;
+   ent->value.dataPtr = dataPtr;
    ent->mUsage = usage;
    
    // Fetch enum table, if any.
    
    ConsoleBaseType* conType = ConsoleBaseType::getType( type );
    AssertFatal( conType, "Dictionary::addVariable - invalid console type" );
-   ent->enumTable = conType->getEnumTable();
+   ent->value.enumTable = conType->getEnumTable();
    
    return ent;
 }
@@ -1031,6 +1141,8 @@ void Namespace::init()
    mGlobalNamespace->mName = NULL;
    mGlobalNamespace->mNext = NULL;
    mNamespaceList = mGlobalNamespace;
+
+   setupDictionaryStack();
 }
 
 Namespace *Namespace::global()
@@ -1268,7 +1380,7 @@ void Namespace::markGroup(const char* name, const char* usage)
 
 extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
 
-const char *Namespace::Entry::execute(S32 argc, const char **argv, ExprEvalState *state)
+const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state)
 {
    if(mType == ConsoleFunctionType)
    {

+ 47 - 98
Engine/source/console/consoleInternal.h

@@ -151,7 +151,7 @@ class Namespace
          void clear();
 
          ///
-         const char *execute( S32 argc, const char** argv, ExprEvalState* state );
+         const char *execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
          
          /// Return a one-line documentation text string for the function.
          String getBriefDescription( String* outRemainingDocText = NULL ) const;
@@ -275,7 +275,7 @@ class Namespace
 
 typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
 
-extern char *typeValueEmpty;
+
 
 class Dictionary
 {
@@ -283,16 +283,9 @@ public:
 
    struct Entry
    {
-      enum
-      {
-         TypeInternalInt = -3,
-         TypeInternalFloat = -2,
-         TypeInternalString = -1,
-      };
-
       StringTableEntry name;
+      ConsoleValue value;
       Entry *nextEntry;
-      S32 type;
 
       typedef Signal<void()> NotifySignal;
 
@@ -306,72 +299,42 @@ public:
       /// Whether this is a constant that cannot be assigned to.
       bool mIsConstant;
 
-   protected:
-
-      // NOTE: This is protected to ensure no one outside
-      // of this structure is messing with it.
-
-      #pragma warning( push )
-      #pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
-
-      // An variable is either a real dynamic type or
-      // its one exposed from C++ using a data pointer.
-      //
-      // We use this nameless union and struct setup
-      // to optimize the memory usage.
-      union
-      {
-         struct
-         {
-            char *sval;
-            U32 ival;  // doubles as strlen when type is TypeInternalString
-            F32 fval;
-            U32 bufferLen;
-         };
-
-         struct
-         {
-            /// The real data pointer.
-            void *dataPtr;
-
-            /// The enum lookup table for enumerated types.
-            const EnumTable *enumTable;
-         };
-      };
-
-      #pragma warning( pop ) // C4201
-
    public:
 
+      Entry() {
+         name = NULL;
+         notify = NULL;
+         nextEntry = NULL;
+         mUsage = NULL;
+         mIsConstant = false;
+         value.init();
+      }
+      
       Entry(StringTableEntry name);
       ~Entry();
+      
+      Entry *mNext;
+      
+      void reset() {
+         name = NULL;
+         value.cleanup();
+         if ( notify )
+            delete notify;
+      }
 
-      U32 getIntValue()
+      inline U32 getIntValue()
       {
-         if(type <= TypeInternalString)
-            return ival;
-         else
-            return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
+         return value.getIntValue();
       }
 
-      F32 getFloatValue()
+      inline F32 getFloatValue()
       {
-         if(type <= TypeInternalString)
-            return fval;
-         else
-            return dAtof(Con::getData(type, dataPtr, 0, enumTable));
+         return value.getFloatValue();
       }
 
-      const char *getStringValue()
+      inline const char *getStringValue()
       {
-         if(type == TypeInternalString)
-            return 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);
+         return value.getStringValue();
       }
 
       void setIntValue(U32 val)
@@ -381,23 +344,8 @@ public:
             Con::errorf( "Cannot assign value to constant '%s'.", name );
             return;
          }
-            
-         if(type <= TypeInternalString)
-         {
-            fval = (F32)val;
-            ival = val;
-            if(sval != typeValueEmpty)
-            {
-               dFree(sval);
-               sval = typeValueEmpty;
-            }
-            type = TypeInternalInt;
-         }
-         else
-         {
-            const char *dptr = Con::getData(TypeS32, &val, 0);
-            Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
-         }
+         
+         value.setIntValue(val);
 
          // Fire off the notification if we have one.
          if ( notify )
@@ -411,30 +359,29 @@ public:
             Con::errorf( "Cannot assign value to constant '%s'.", name );
             return;
          }
+         
+         value.setFloatValue(val);
 
-         if(type <= TypeInternalString)
-         {
-            fval = val;
-            ival = static_cast<U32>(val);
-            if(sval != typeValueEmpty)
-            {
-               dFree(sval);
-               sval = typeValueEmpty;
-            }
-            type = TypeInternalFloat;
-         }
-         else
+         // Fire off the notification if we have one.
+         if ( notify )
+            notify->trigger();
+      }
+
+      void setStringValue(const char *newValue)
+      {
+         if( mIsConstant )
          {
-            const char *dptr = Con::getData(TypeF32, &val, 0);
-            Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
+            Con::errorf( "Cannot assign value to constant '%s'.", name );
+            return;
          }
-
+         
+         value.setStringValue(newValue);
+         
+         
          // Fire off the notification if we have one.
          if ( notify )
             notify->trigger();
       }
-
-      void setStringValue(const char *value);
    };
 
     struct HashTableData
@@ -473,6 +420,8 @@ public:
 
     void setVariable(StringTableEntry name, const char *value);
     const char *getVariable(StringTableEntry name, bool *valid = NULL);
+    S32 getIntVariable(StringTableEntry name, bool *valid = NULL);
+	F32 getFloatVariable(StringTableEntry name, bool *entValid = NULL);
     
     U32 getCount() const
     {

+ 1 - 1
Engine/source/console/consoleLogger.cpp

@@ -79,7 +79,7 @@ void ConsoleLogger::initPersistFields()
 
 //-----------------------------------------------------------------------------
 
-bool ConsoleLogger::processArguments( S32 argc, const char **argv )
+bool ConsoleLogger::processArguments( S32 argc, ConsoleValueRef *argv )
 {
    if( argc == 0 )
       return false;

+ 1 - 1
Engine/source/console/consoleLogger.h

@@ -81,7 +81,7 @@ class ConsoleLogger : public SimObject
       /// // Example script constructor usage.
       /// %obj = new ConsoleLogger( objName, logFileName, [append = false] );
       /// @endcode
-      bool processArguments( S32 argc, const char **argv );
+      bool processArguments( S32 argc, ConsoleValueRef *argv );
 
       /// Default constructor, make sure to initalize
       ConsoleLogger();

+ 69 - 64
Engine/source/console/engineAPI.h

@@ -145,12 +145,12 @@ inline const char* EngineMarshallData( U32 value )
 /// Marshal data from native into client form stored directly in
 /// client function invocation vector.
 template< typename T >
-inline void EngineMarshallData( const T& arg, S32& argc, const char** argv )
+inline void EngineMarshallData( const T& arg, S32& argc, ConsoleValueRef *argv )
 {
    argv[ argc ] = Con::getStringArg( castConsoleTypeToString( arg ) );
    argc ++;
 }
-inline void EngineMarshallData( bool arg, S32& argc, const char** argv )
+inline void EngineMarshallData( bool arg, S32& argc, ConsoleValueRef *argv )
 {
    if( arg )
       argv[ argc ] = "1";
@@ -158,33 +158,33 @@ inline void EngineMarshallData( bool arg, S32& argc, const char** argv )
       argv[ argc ] = "0";
    argc ++;
 }
-inline void EngineMarshallData( S32 arg, S32& argc, const char** argv )
+inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValueRef *argv )
 {
    argv[ argc ] = Con::getIntArg( arg );
    argc ++;
 }
-inline void EngineMarshallData( U32 arg, S32& argc, const char** argv )
+inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValueRef *argv )
 {
    EngineMarshallData( S32( arg ), argc, argv );
 }
-inline void EngineMarshallData( F32 arg, S32& argc, const char** argv )
+inline void EngineMarshallData( F32 arg, S32& argc, ConsoleValueRef *argv )
 {
    argv[ argc ] = Con::getFloatArg( arg );
    argc ++;
 }
-inline void EngineMarshallData( const char* arg, S32& argc, const char** argv )
+inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValueRef *argv )
 {
    argv[ argc ] = arg;
    argc ++;
 }
 template< typename T >
-inline void EngineMarshallData( T* object, S32& argc, const char** argv )
+inline void EngineMarshallData( T* object, S32& argc, ConsoleValueRef *argv )
 {
    argv[ argc ] = ( object ? object->getIdString() : "0" );
    argc ++;
 }
 template< typename T >
-inline void EngineMarshallData( const T* object, S32& argc, const char** argv )
+inline void EngineMarshallData( const T* object, S32& argc, ConsoleValueRef *argv )
 {
    argv[ argc ] = ( object ? object->getIdString() : "0" );
    argc ++;
@@ -1391,12 +1391,12 @@ struct _EngineConsoleThunk< startArgc, R() >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 0;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
    {
       return _EngineConsoleThunkReturnValue( fn() );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
    {
       return _EngineConsoleThunkReturnValue( ( frame->*fn )() );
    }
@@ -1406,12 +1406,12 @@ struct _EngineConsoleThunk< startArgc, void() >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 0;
-   static void thunk( S32 argc, const char** argv, void ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
    {
       fn();
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
    {
       return ( frame->*fn )();
    }
@@ -1422,13 +1422,13 @@ struct _EngineConsoleThunk< startArgc, R( A ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 1 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       return _EngineConsoleThunkReturnValue( fn( a ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       return _EngineConsoleThunkReturnValue( ( frame->*fn )( a ) );
@@ -1439,13 +1439,13 @@ struct _EngineConsoleThunk< startArgc, void( A ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 1 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       fn( a );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       ( frame->*fn )( a );
@@ -1457,14 +1457,14 @@ struct _EngineConsoleThunk< startArgc, R( A, B ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 2 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
       return _EngineConsoleThunkReturnValue( fn( a, b ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1476,14 +1476,14 @@ struct _EngineConsoleThunk< startArgc, void( A, B ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 2 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
       fn( a, b );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1496,7 +1496,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 3 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1504,7 +1504,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1517,7 +1517,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 3 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1525,7 +1525,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C ) >
       fn( a, b, c );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1539,7 +1539,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 4 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1548,7 +1548,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1562,7 +1562,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 4 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1571,7 +1571,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) >
       fn( a, b, c, d );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1586,7 +1586,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 5 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1596,7 +1596,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1611,7 +1611,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 5 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1621,7 +1621,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) >
       fn( a, b, c, d, e );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1637,7 +1637,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 6 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1648,7 +1648,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1664,7 +1664,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 6 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1675,7 +1675,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) >
       fn( a, b, c, d, e, f );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1692,7 +1692,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 7 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1704,7 +1704,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1721,7 +1721,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 7 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1733,7 +1733,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) >
       fn( a, b, c, d, e, f, g );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1751,7 +1751,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 8 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1764,7 +1764,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1782,7 +1782,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 8 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1795,7 +1795,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) >
       fn( a, b, c, d, e, f, g, h );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1814,7 +1814,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 9 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1828,7 +1828,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1847,7 +1847,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 9 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1861,7 +1861,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) >
       fn( a, b, c, d, e, f, g, h, i );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1881,7 +1881,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 10 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1896,7 +1896,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1916,7 +1916,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 10 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1931,7 +1931,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) >
       fn( a, b, c, d, e, f, g, h, i, j );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1951,7 +1951,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const int NUM_ARGS = 11 + startArgc;
-   static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -1967,7 +1967,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) >
       return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j, k ) );
    }
    template< typename Frame >
-   static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
+   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -1988,7 +1988,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
 {
    typedef void ReturnType;
    static const int NUM_ARGS = 11 + startArgc;
-   static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
@@ -2004,7 +2004,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
       fn( a, b, c, d, e, f, g, h, i, j, k );
    }
    template< typename Frame >
-   static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
+   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
    {
       A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
       B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
@@ -2088,7 +2088,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
       ( void* ) &fn ## name,                                                                                                     \
       0                                                                                                                          \
    );                                                                                                                            \
-   static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, const char** argv )       \
+   static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )       \
    {                                                                                                                             \
       return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                \
          argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs                                                            \
@@ -2168,7 +2168,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
       ( void* ) &fn ## className ## _ ## name,                                                                                                  \
       0                                                                                                                                         \
    );                                                                                                                                           \
-   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, const char** argv )  \
+   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv )  \
    {                                                                                                                                            \
       _ ## className ## name ## frame frame;                                                                                                    \
       frame.object = static_cast< className* >( object );                                                                                       \
@@ -2225,7 +2225,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
       ( void* ) &fn ## className ## _ ## name,                                                                                         \
       0                                                                                                                                \
    );                                                                                                                                  \
-   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, const char** argv )\
+   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
    {                                                                                                                                   \
       return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                      \
          argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs                                        \
@@ -2249,7 +2249,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
 #define DefineConsoleFunction( name, returnType, args, defaultArgs, usage )                                                      \
    static inline returnType _fn ## name ## impl args;                                                                            \
    static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs;                                   \
-   static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, const char** argv )       \
+   static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )       \
    {                                                                                                                             \
       return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                \
          argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs                                                            \
@@ -2274,7 +2274,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
    };                                                                                                                                           \
    static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType >                \
       _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
-   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, const char** argv )  \
+   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv )  \
    {                                                                                                                                            \
       _ ## className ## name ## frame frame;                                                                                                    \
       frame.object = static_cast< className* >( object );                                                                                       \
@@ -2296,7 +2296,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
 #define DefineConsoleStaticMethod( className, name, returnType, args, defaultArgs, usage )                                             \
    static inline returnType _fn ## className ## name ## impl args;                                                                     \
    static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
-   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, const char** argv )\
+   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
    {                                                                                                                                   \
       return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                      \
          argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs                                        \
@@ -2619,14 +2619,19 @@ struct _EngineConsoleCallbackHelper
 
       SimObject* mThis;
       S32 mArgc;
-      const char* mArgv[ MAX_ARGUMENTS + 2 ];
+      ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ];
       
       const char* _exec()
       {
          if( mThis )
          {
             // Cannot invoke callback until object has been registered
-            return mThis->isProperlyAdded() ? Con::execute( mThis, mArgc, mArgv ) : "";
+			if (mThis->isProperlyAdded()) {
+				return Con::execute( mThis, mArgc, mArgv );
+			} else {
+				Con::resetStackFrame(); // jamesu - we might have pushed some vars here
+				return "";
+			}
          }
          else
             return Con::execute( mArgc, mArgv );

+ 2 - 2
Engine/source/console/engineDoc.cpp

@@ -114,7 +114,7 @@ static void dumpVariable(  Stream& stream,
 {
    // Skip variables defined in script.
    
-   if( entry->type < 0 )
+   if( entry->value.type < 0 )
       return;
          
    // Skip internals... don't export them.
@@ -149,7 +149,7 @@ static void dumpVariable(  Stream& stream,
             
    // Skip variables for which we can't decipher their type.
 
-   ConsoleBaseType* type = ConsoleBaseType::getType( entry->type );
+   ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.type );
    if( !type )
    {
       Con::errorf( "Can't find type for variable '%s'", entry->name );

+ 5 - 5
Engine/source/console/sim.cpp

@@ -138,20 +138,20 @@ ConsoleDocFragment _spawnObject1(
 ConsoleFunction(spawnObject, S32, 3, 6, "spawnObject(class [, dataBlock, name, properties, script])"
 				"@hide")
 {
-   String spawnClass(argv[1]);
+   String spawnClass((String)argv[1]);
    String spawnDataBlock;
    String spawnName;
    String spawnProperties;
    String spawnScript;
 
    if (argc >= 3)
-      spawnDataBlock = argv[2];
+      spawnDataBlock = (String)argv[2];
    if (argc >= 4)
-      spawnName = argv[3];
+      spawnName = (String)argv[3];
    if (argc >= 5)
-      spawnProperties = argv[4];
+      spawnProperties = (String)argv[4];
    if (argc >= 6)
-      spawnScript = argv[5];
+      spawnScript = (String)argv[5];
 
    SimObject* spawnObject = Sim::spawnObject(spawnClass, spawnDataBlock, spawnName, spawnProperties, spawnScript);
 

+ 21 - 23
Engine/source/console/simEvents.cpp

@@ -28,30 +28,26 @@
 // Stupid globals not declared in a header
 extern ExprEvalState gEvalState;
 
-SimConsoleEvent::SimConsoleEvent(S32 argc, const char **argv, bool onObject)
+SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject)
 {
    mOnObject = onObject;
    mArgc = argc;
-   U32 totalSize = 0;
-   S32 i;
-   for(i = 0; i < argc; i++)
-      totalSize += dStrlen(argv[i]) + 1;
-   totalSize += sizeof(char *) * argc;
 
-   mArgv = (char **) dMalloc(totalSize);
-   char *argBase = (char *) &mArgv[argc];
-
-   for(i = 0; i < argc; i++)
-   {
-      mArgv[i] = argBase;
-      dStrcpy(mArgv[i], argv[i]);
-      argBase += dStrlen(argv[i]) + 1;
+   mArgv = new ConsoleValueRef[argc];
+   for (int i=0; i<argc; i++) {
+	  mArgv[i].value = new ConsoleValue();
+	  mArgv[i].value->type = ConsoleValue::TypeInternalString;
+	  mArgv[i].value->init();
+      mArgv[i].value->setStringValue((const char*)argv[i]);
    }
 }
 
 SimConsoleEvent::~SimConsoleEvent()
 {
-   dFree(mArgv);
+   for (int i=0; i<mArgc; i++) {
+      delete mArgv[i].value;
+   }
+   delete[] mArgv;
 }
 
 void SimConsoleEvent::process(SimObject* object)
@@ -60,12 +56,14 @@ void SimConsoleEvent::process(SimObject* object)
    //    Con::printf("Executing schedule: %d", sequenceCount);
    // #endif
    if(mOnObject)
-      Con::execute(object, mArgc, const_cast<const char**>( mArgv ));
+      Con::execute(object, mArgc, mArgv );
    else
    {
       // Grab the function name. If '::' doesn't exist, then the schedule is
       // on a global function.
-      char* func = dStrstr( mArgv[0], (char*)"::" );
+      char funcName[256];
+      dStrncpy(funcName, (const char*)mArgv[0], 256);
+      char* func = dStrstr( funcName, (char*)"::" );
       if( func )
       {
          // Set the first colon to NULL, so we can reference the namespace.
@@ -77,18 +75,18 @@ void SimConsoleEvent::process(SimObject* object)
          func += 2;
 
          // Lookup the namespace and function entry.
-         Namespace* ns = Namespace::find( StringTable->insert( mArgv[0] ) );
+         Namespace* ns = Namespace::find( StringTable->insert( funcName ) );
          if( ns )
          {
             Namespace::Entry* nse = ns->lookup( StringTable->insert( func ) );
             if( nse )
                // Execute.
-               nse->execute( mArgc, (const char**)mArgv, &gEvalState );
+               nse->execute( mArgc, mArgv, &gEvalState );
          }
       }
 
       else
-         Con::execute(mArgc, const_cast<const char**>( mArgv ));
+         Con::execute(mArgc, mArgv );
    }
 }
 
@@ -122,7 +120,7 @@ const char *SimConsoleThreadExecCallback::waitForResult()
 
 //-----------------------------------------------------------------------------
 
-SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, const char **argv, bool onObject, SimConsoleThreadExecCallback *callback) :
+SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback) :
    SimConsoleEvent(argc, argv, onObject), cb(callback)
 {
 }
@@ -131,9 +129,9 @@ void SimConsoleThreadExecEvent::process(SimObject* object)
 {
    const char *retVal;
    if(mOnObject)
-      retVal = Con::execute(object, mArgc, const_cast<const char**>( mArgv ));
+      retVal = Con::execute(object, mArgc, mArgv);
    else
-      retVal = Con::execute(mArgc, const_cast<const char**>( mArgv ));
+      retVal = Con::execute(mArgc, mArgv);
 
    if(cb)
       cb->handleCallback(retVal);

+ 6 - 3
Engine/source/console/simEvents.h

@@ -34,6 +34,7 @@
 // Forward Refs
 class SimObject;
 class Semaphore;
+class ConsoleValue;
 
 /// Represents a queued event in the sim.
 ///
@@ -82,6 +83,8 @@ public:
    virtual void process(SimObject *object)=0;
 };
 
+class ConsoleValueRef;
+
 /// Implementation of schedule() function.
 ///
 /// This allows you to set a console function to be
@@ -90,7 +93,7 @@ class SimConsoleEvent : public SimEvent
 {
 protected:
    S32 mArgc;
-   char **mArgv;
+   ConsoleValueRef *mArgv;
    bool mOnObject;
 public:
 
@@ -107,7 +110,7 @@ public:
    ///
    /// @see Con::execute(S32 argc, const char *argv[])
    /// @see Con::execute(SimObject *object, S32 argc, const char *argv[])
-   SimConsoleEvent(S32 argc, const char **argv, bool onObject);
+   SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject);
 
    ~SimConsoleEvent();
    virtual void process(SimObject *object);
@@ -131,7 +134,7 @@ class SimConsoleThreadExecEvent : public SimConsoleEvent
    SimConsoleThreadExecCallback *cb;
 
 public:
-   SimConsoleThreadExecEvent(S32 argc, const char **argv, bool onObject, SimConsoleThreadExecCallback *callback);
+   SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback);
 
    virtual void process(SimObject *object);
 };

+ 1 - 1
Engine/source/console/simObject.cpp

@@ -123,7 +123,7 @@ SimObject::~SimObject()
 
 //-----------------------------------------------------------------------------
 
-bool SimObject::processArguments(S32 argc, const char**argv)
+bool SimObject::processArguments(S32 argc, ConsoleValueRef *argv)
 {
    return argc == 0;
 }

+ 1 - 1
Engine/source/console/simObject.h

@@ -540,7 +540,7 @@ class SimObject: public ConsoleObject
       
       virtual ~SimObject();
 
-      virtual bool processArguments(S32 argc, const char **argv);  ///< Process constructor options. (ie, new SimObject(1,2,3))
+      virtual bool processArguments(S32 argc, ConsoleValueRef *argv);  ///< Process constructor options. (ie, new SimObject(1,2,3))
 
       /// @}
 

+ 1 - 1
Engine/source/console/simObjectList.cpp

@@ -117,7 +117,7 @@ S32 QSORT_CALLBACK SimObjectList::_callbackSort( const void *a, const void *b )
    static char idB[64];
    dSprintf( idB, sizeof( idB ), "%d", objB->getId() );
 
-   return dAtoi( Con::executef( smSortScriptCallbackFn, idA, idB ) );
+   return dAtoi( Con::executef( (const char*)smSortScriptCallbackFn, idA, idB ) );
 }
 
 void SimObjectList::scriptSort( const String &scriptCallback )

+ 1 - 1
Engine/source/console/simPersistSet.cpp

@@ -46,7 +46,7 @@ SimPersistSet::SimPersistSet()
 
 //-----------------------------------------------------------------------------
 
-bool SimPersistSet::processArguments( S32 argc, const char** argv )
+bool SimPersistSet::processArguments( S32 argc, ConsoleValueRef *argv )
 {
    for( U32 i = 0; i < argc; ++ i )
    {

+ 1 - 1
Engine/source/console/simPersistSet.h

@@ -58,7 +58,7 @@ class SimPersistSet : public SimSet
       // SimSet.
       virtual void addObject( SimObject* );
       virtual void write( Stream &stream, U32 tabStop, U32 flags = 0 );
-      virtual bool processArguments( S32 argc, const char** argv );
+      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
       
       DECLARE_CONOBJECT( SimPersistSet );
       DECLARE_CATEGORY( "Console" );

+ 6 - 6
Engine/source/console/simSet.cpp

@@ -228,11 +228,11 @@ void SimSet::scriptSort( const String &scriptCallbackFn )
 
 //-----------------------------------------------------------------------------
 
-void SimSet::callOnChildren( const String &method, S32 argc, const char *argv[], bool executeOnChildGroups )
+void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups )
 {
    // Prep the arguments for the console exec...
    // Make sure and leave args[1] empty.
-   const char* args[21];
+   ConsoleValueRef args[21];
    args[0] = method.c_str();
    for (S32 i = 0; i < argc; i++)
       args[i + 2] = argv[i];
@@ -834,7 +834,7 @@ SimGroup* SimGroup::deepClone()
 
 //-----------------------------------------------------------------------------
 
-bool SimGroup::processArguments(S32, const char **)
+bool SimGroup::processArguments(S32, ConsoleValueRef *argv)
 {
    return true;
 }
@@ -973,7 +973,7 @@ ConsoleMethod( SimSet, callOnChildren, void, 3, 0,
    "@note This method recurses into all SimSets that are children to the set.\n\n"
    "@see callOnChildrenNoRecurse" )
 {
-   object->callOnChildren( argv[2], argc - 3, argv + 3 );
+   object->callOnChildren( (const char*)argv[2], argc - 3, argv + 3 );
 }
 
 //-----------------------------------------------------------------------------
@@ -985,7 +985,7 @@ ConsoleMethod( SimSet, callOnChildrenNoRecurse, void, 3, 0,
    "@note This method does not recurse into child SimSets.\n\n"
    "@see callOnChildren" )
 {
-   object->callOnChildren( argv[2], argc - 3, argv + 3, false );
+   object->callOnChildren( (const char*)argv[2], argc - 3, argv + 3, false );
 }
 
 //-----------------------------------------------------------------------------
@@ -1121,7 +1121,7 @@ DefineEngineMethod( SimSet, pushToBack, void, ( SimObject* obj ),,
 ConsoleMethod( SimSet, sort, void, 3, 3, "( string callbackFunction ) Sort the objects in the set using the given comparison function.\n"
    "@param callbackFunction Name of a function that takes two object arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal." )
 {
-   object->scriptSort( argv[2] );
+   object->scriptSort( (const char*)argv[2] );
 }
 
 //-----------------------------------------------------------------------------

+ 2 - 2
Engine/source/console/simSet.h

@@ -214,7 +214,7 @@ class SimSet: public SimObject
       
       /// @}
 
-      void callOnChildren( const String &method, S32 argc, const char *argv[], bool executeOnChildGroups = true );
+      void callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups = true );
 
       /// Return the number of objects in this set as well as all sets that are contained
       /// in this set and its children.
@@ -434,7 +434,7 @@ class SimGroup: public SimSet
       virtual SimObject* findObject(const char* name);
       virtual void onRemove();
 
-      virtual bool processArguments( S32 argc, const char** argv );
+      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
 
       DECLARE_CONOBJECT( SimGroup );
 };

+ 166 - 8
Engine/source/console/stringStack.cpp

@@ -20,22 +20,180 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+#include <stdio.h>
+#include "console/consoleInternal.h"
 #include "console/stringStack.h"
 
-void StringStack::getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame /* = false */)
+
+void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame /* = false */)
 {
-   U32 startStack = mFrameOffsets[mNumFrames-1] + 1;
-   U32 argCount   = getMin(mStartStackSize - startStack, (U32)MaxArgs - 1);
+   U32 startStack = mStackFrames[mFrame-1];
+   U32 argCount   = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
 
-   *in_argv = mArgV;
-   mArgV[0] = name;
+   *in_argv = mArgv;
+   mArgv[0] = name;
    
-   for(U32 i = 0; i < argCount; i++)
-      mArgV[i+1] = mBuffer + mStartOffsets[startStack + i];
+   for(U32 i = 0; i < argCount; i++) {
+	  ConsoleValueRef *ref = &mArgv[i+1];
+	  ref->value = &mStack[startStack + i];
+	  ref->stringStackValue = NULL;
+   }
    argCount++;
    
    *argc = argCount;
 
    if(popStackFrame)
       popFrame();
-}
+}
+
+ConsoleValueStack::ConsoleValueStack() : 
+mFrame(0),
+mStackPos(0)
+{
+	for (int i=0; i<ConsoleValueStack::MaxStackDepth; i++) {
+		mStack[i].init();
+		mStack[i].type = ConsoleValue::TypeInternalString;
+	}
+}
+
+ConsoleValueStack::~ConsoleValueStack()
+{
+}
+
+void ConsoleValueStack::pushVar(ConsoleValue *variable)
+{
+	if (mStackPos == ConsoleValueStack::MaxStackDepth) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return;
+	}
+
+	switch (variable->type)
+	{
+	case ConsoleValue::TypeInternalInt:
+		mStack[mStackPos++].setIntValue((S32)variable->getIntValue());
+	case ConsoleValue::TypeInternalFloat:
+		mStack[mStackPos++].setFloatValue((F32)variable->getFloatValue());
+	default:
+		mStack[mStackPos++].setStackStringValue(variable->getStringValue());
+	}
+}
+
+void ConsoleValueStack::pushValue(ConsoleValue &variable)
+{
+	if (mStackPos == ConsoleValueStack::MaxStackDepth) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return;
+	}
+
+	switch (variable.type)
+	{
+	case ConsoleValue::TypeInternalInt:
+		mStack[mStackPos++].setIntValue((S32)variable.getIntValue());
+	case ConsoleValue::TypeInternalFloat:
+		mStack[mStackPos++].setFloatValue((F32)variable.getFloatValue());
+	default:
+		mStack[mStackPos++].setStringValue(variable.getStringValue());
+	}
+}
+
+ConsoleValue *ConsoleValueStack::pushString(const char *value)
+{
+	if (mStackPos == ConsoleValueStack::MaxStackDepth) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return NULL;
+	}
+
+	//Con::printf("[%i]CSTK pushString %s", mStackPos, value);
+
+	mStack[mStackPos++].setStringValue(value);
+	return &mStack[mStackPos-1];
+}
+
+ConsoleValue *ConsoleValueStack::pushStackString(const char *value)
+{
+	if (mStackPos == ConsoleValueStack::MaxStackDepth) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return NULL;
+	}
+
+	//Con::printf("[%i]CSTK pushString %s", mStackPos, value);
+
+	mStack[mStackPos++].setStackStringValue(value);
+	return &mStack[mStackPos-1];
+}
+
+ConsoleValue *ConsoleValueStack::pushUINT(U32 value)
+{
+	if (mStackPos == ConsoleValueStack::MaxStackDepth) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return NULL;
+	}
+
+	//Con::printf("[%i]CSTK pushUINT %i", mStackPos, value);
+
+	mStack[mStackPos++].setIntValue(value);
+	return &mStack[mStackPos-1];
+}
+
+ConsoleValue *ConsoleValueStack::pushFLT(float value)
+{
+	if (mStackPos == ConsoleValueStack::MaxStackDepth) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return NULL;
+	}
+
+	//Con::printf("[%i]CSTK pushFLT %f", mStackPos, value);
+
+	mStack[mStackPos++].setFloatValue(value);
+	return &mStack[mStackPos-1];
+}
+
+static ConsoleValue gNothing;
+
+ConsoleValue* ConsoleValueStack::pop()
+{
+	if (mStackPos == 0) {
+		AssertFatal(false, "Console Value Stack is empty");
+		return &gNothing;
+	}
+
+	return &mStack[--mStackPos];
+}
+
+void ConsoleValueStack::pushFrame()
+{
+	//Con::printf("CSTK pushFrame");
+	mStackFrames[mFrame++] = mStackPos;
+}
+
+void ConsoleValueStack::resetFrame()
+{
+	if (mFrame == 0) {
+		mStackPos = 0;
+		return;
+	}
+
+	U32 start = mStackFrames[mFrame-1];
+	//for (U32 i=start; i<mStackPos; i++) {
+		//mStack[i].clear();
+	//}
+	mStackPos = start;
+	//Con::printf("CSTK resetFrame to %i", mStackPos);
+}
+
+void ConsoleValueStack::popFrame()
+{
+	//Con::printf("CSTK popFrame");
+	if (mFrame == 0) {
+		// Go back to start
+		mStackPos = 0;
+		return;
+	}
+
+	U32 start = mStackFrames[mFrame-1];
+	//for (U32 i=start; i<mStackPos; i++) {
+		//mStack[i].clear();
+	//}
+	mStackPos = start;
+	mFrame--;
+}

+ 45 - 0
Engine/source/console/stringStack.h

@@ -36,6 +36,8 @@
 #endif
 
 
+
+
 /// Core stack for interpreter operations.
 ///
 /// This class provides some powerful semantics for working with strings, and is
@@ -185,6 +187,11 @@ struct StringStack
       return mBuffer + mStart;
    }
 
+   inline const char *getPreviousStringValue()
+   {
+      return mBuffer + mStartOffsets[mStartStackSize-1];
+   }
+
    /// Advance the start stack, placing a zero length string on the top.
    ///
    /// @note You should use StringStack::push, not this, if you want to
@@ -275,4 +282,42 @@ struct StringStack
    void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
 };
 
+
+// New console value stack
+class ConsoleValueStack
+{
+   enum {
+      MaxStackDepth = 1024,
+      MaxArgs = 20,
+      ReturnBufferSpace = 512
+   };
+public:
+	ConsoleValueStack();
+	~ConsoleValueStack();
+
+	void pushVar(ConsoleValue *variable);
+	void pushValue(ConsoleValue &value);
+	ConsoleValue* pop();
+
+    ConsoleValue *pushString(const char *value);
+    ConsoleValue *pushStackString(const char *value);
+    ConsoleValue *pushUINT(U32 value);
+    ConsoleValue *pushFLT(float value);
+
+	void pushFrame();
+	void popFrame();
+
+	void resetFrame();
+
+    void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);
+
+	ConsoleValue mStack[MaxStackDepth];
+	U32 mStackFrames[MaxStackDepth];
+
+	U32 mFrame;
+	U32 mStackPos;
+
+	ConsoleValueRef mArgv[MaxArgs];
+};
+
 #endif

+ 2 - 2
Engine/source/core/fileObject.cpp

@@ -493,9 +493,9 @@ ConsoleMethod( FileObject, writeObject, void, 3, 4, "FileObject.writeObject(SimO
       return;
    }
 
-   char *objName = NULL;
+   const char *objName = NULL;
    if( argc == 4 )
-      objName = (char*)argv[3];
+      objName = (const char*)argv[3];
 
    object->writeObject( obj, (const U8*)objName );
 }

+ 1 - 1
Engine/source/environment/editors/guiMeshRoadEditorCtrl.cpp

@@ -1040,7 +1040,7 @@ void GuiMeshRoadEditorCtrl::setMode( String mode, bool sourceShortcut = false )
    mMode = mode;
 
 	if( sourceShortcut )
-		Con::executef( this, "paletteSync", mode );
+		Con::executef( this, "paletteSync", (const char*)mode );
 }
 
 void GuiMeshRoadEditorCtrl::setSelectedRoad( MeshRoad *road )

+ 1 - 1
Engine/source/environment/editors/guiRiverEditorCtrl.cpp

@@ -1181,7 +1181,7 @@ void GuiRiverEditorCtrl::setMode( String mode, bool sourceShortcut = false )
    mMode = mode;
 
 	if( sourceShortcut )
-		Con::executef( this, "paletteSync", mode );
+		Con::executef( this, "paletteSync", mode.utf8() );
 }
 
 void GuiRiverEditorCtrl::setSelectedRiver( River *river )

+ 1 - 1
Engine/source/environment/editors/guiRoadEditorCtrl.cpp

@@ -945,7 +945,7 @@ void GuiRoadEditorCtrl::setMode( String mode, bool sourceShortcut = false )
    mMode = mode;
 
 	if( sourceShortcut )
-		Con::executef( this, "paletteSync", mode );
+		Con::executef( this, "paletteSync", mode.utf8() );
 }
 
 void GuiRoadEditorCtrl::setSelectedRoad( DecalRoad *road )

+ 1 - 1
Engine/source/environment/waterObject.cpp

@@ -406,7 +406,7 @@ void WaterObject::inspectPostApply()
    setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask );
 }
 
-bool WaterObject::processArguments( S32 argc, const char **argv )
+bool WaterObject::processArguments( S32 argc, ConsoleValueRef *argv )
 {
    if( typeid( *this ) == typeid( WaterObject ) )
    {

+ 1 - 1
Engine/source/environment/waterObject.h

@@ -156,7 +156,7 @@ public:
    virtual bool onAdd();
    virtual void onRemove();
    virtual void inspectPostApply();
-   virtual bool processArguments(S32 argc, const char **argv);
+   virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
 
    // NetObject
    virtual U32  packUpdate( NetConnection * conn, U32 mask, BitStream *stream );

+ 1 - 1
Engine/source/gui/controls/guiMaterialCtrl.cpp

@@ -169,5 +169,5 @@ void GuiMaterialCtrl::onRender( Point2I offset, const RectI &updateRect )
 ConsoleMethod( GuiMaterialCtrl, setMaterial, bool, 3, 3, "( string materialName )"
                "Set the material to be displayed in the control." )
 {
-   return object->setMaterial( argv[2] );
+   return object->setMaterial( (const char*)argv[2] );
 }

+ 1 - 1
Engine/source/gui/controls/guiTreeViewCtrl.cpp

@@ -4928,7 +4928,7 @@ ConsoleMethod( GuiTreeViewCtrl, setItemTooltip, void, 4, 4, "( int id, string te
       return;
    }
    
-   item->mTooltip = argv[ 3 ];
+   item->mTooltip = (String)argv[ 3 ];
 }
 
 ConsoleMethod( GuiTreeViewCtrl, setItemImages, void, 5, 5, "( int id, int normalImage, int expandedImage ) - Sets the normal and expanded images to show for the given item." )

+ 1 - 1
Engine/source/gui/core/guiControl.cpp

@@ -308,7 +308,7 @@ void GuiControl::initPersistFields()
 
 //-----------------------------------------------------------------------------
 
-bool GuiControl::processArguments(S32 argc, const char **argv)
+bool GuiControl::processArguments(S32 argc, ConsoleValueRef *argv)
 {
    // argv[0] - The GuiGroup to add this control to when it's created.  
    //           this is an optional parameter that may be specified at

+ 1 - 1
Engine/source/gui/core/guiControl.h

@@ -330,7 +330,7 @@ class GuiControl : public SimGroup
       
       GuiControl();
       virtual ~GuiControl();
-      virtual bool processArguments(S32 argc, const char **argv);
+      virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
       
       static void initPersistFields();
       static void consoleInit();

+ 2 - 3
Engine/source/gui/editor/guiFilterCtrl.cpp

@@ -83,10 +83,9 @@ ConsoleMethod( GuiFilterCtrl, setValue, void, 3, 20, "(f1, f2, ...)"
 {
    Filter filter;
 
-   argc -= 2;
-   argv += 2;
+   StringStackWrapper args(argc - 2, argv + 2);
 
-   filter.set(argc, argv);
+   filter.set(args.count(), args);
 	object->set(filter);
 }
 

+ 1 - 1
Engine/source/gui/editor/inspector/variableInspector.cpp

@@ -63,5 +63,5 @@ void GuiVariableInspector::loadVars( String searchStr )
 
 ConsoleMethod( GuiVariableInspector, loadVars, void, 3, 3, "loadVars( searchString )" )
 {
-   object->loadVars( argv[2] );
+   object->loadVars( (const char*)argv[2] );
 }

+ 1 - 1
Engine/source/gui/worldEditor/creator.cpp

@@ -264,7 +264,7 @@ ConsoleMethod( CreatorTree, fileNameMatch, bool, 5, 5, "(string world, string ty
    if(dToupper(argv[4][0]) != dToupper(argv[2][0]))
       return(false);
 
-   return(!dStrnicmp(argv[4]+1, argv[3], typeLen));
+   return(!dStrnicmp(((const char*)argv[4])+1, argv[3], typeLen));
 }
 
 ConsoleMethod( CreatorTree, getSelected, S32, 2, 2, "Return a handle to the currently selected item.")

+ 2 - 2
Engine/source/gui/worldEditor/editorIconRegistry.cpp

@@ -175,7 +175,7 @@ ConsoleStaticMethod( EditorIconRegistry, add, void, 3, 4, "( String className, S
    if ( argc > 3 )
       overwrite = dAtob( argv[3] );
 
-   gEditorIcons.add( argv[1], argv[2], overwrite );
+   gEditorIcons.add( (const char*)argv[1], (const char*)argv[2], overwrite );
 }
 
 ConsoleStaticMethod( EditorIconRegistry, loadFromPath, void, 2, 3, "( String imagePath [, bool overwrite = true] )"
@@ -185,7 +185,7 @@ ConsoleStaticMethod( EditorIconRegistry, loadFromPath, void, 2, 3, "( String ima
    if ( argc > 2 )
       overwrite = dAtob( argv[2] );
 
-   gEditorIcons.loadFromPath( argv[1], overwrite );
+   gEditorIcons.loadFromPath( (const char*)argv[1], overwrite );
 }
 
 ConsoleStaticMethod( EditorIconRegistry, clear, void, 1, 1, "" 

+ 2 - 2
Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp

@@ -782,7 +782,7 @@ void GuiDecalEditorCtrl::setMode( String mode, bool sourceShortcut = false )
 	mMode = mode;
 
 	if( sourceShortcut )
-		Con::executef( this, "paletteSync", mMode );
+		Con::executef( this, "paletteSync", (const char*)mMode );
 }
 
 ConsoleMethod( GuiDecalEditorCtrl, deleteSelectedDecal, void, 2, 2, "deleteSelectedDecal()" )
@@ -894,7 +894,7 @@ ConsoleMethod( GuiDecalEditorCtrl, getSelectionCount, S32, 2, 2, "" )
 ConsoleMethod( GuiDecalEditorCtrl, retargetDecalDatablock, void, 4, 4, "" )
 {
    if( dStrcmp( argv[2], "" ) != 0 && dStrcmp( argv[3], "" ) != 0 )
-		object->retargetDecalDatablock( argv[2], argv[3] );
+		object->retargetDecalDatablock( (const char*)argv[2], (const char*)argv[3] );
 }
 
 void GuiDecalEditorCtrl::setGizmoFocus( DecalInstance * decalInstance )

+ 2 - 2
Engine/source/gui/worldEditor/terrainEditor.cpp

@@ -2714,7 +2714,7 @@ ConsoleMethod(TerrainEditor, updateMaterial, bool, 4, 4,
    if ( index >= terr->getMaterialCount() )
       return false;
 
-   terr->updateMaterial( index, argv[3] );
+   terr->updateMaterial( index, (const char*)argv[3] );
 
    object->setDirty();
 
@@ -2729,7 +2729,7 @@ ConsoleMethod(TerrainEditor, addMaterial, S32, 3, 3,
    if ( !terr )
       return false;
    
-   terr->addMaterial( argv[2] );
+   terr->addMaterial( (const char*)argv[2] );
 
    object->setDirty();
 

+ 2 - 2
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -2758,7 +2758,7 @@ void WorldEditor::initPersistFields()
 //------------------------------------------------------------------------------
 // These methods are needed for the console interfaces.
 
-void WorldEditor::ignoreObjClass( U32 argc, const char **argv )
+void WorldEditor::ignoreObjClass( U32 argc, ConsoleValueRef *argv )
 {
    for(S32 i = 2; i < argc; i++)
    {
@@ -3542,7 +3542,7 @@ void WorldEditor::colladaExportSelection( const String &path )
 ConsoleMethod( WorldEditor, colladaExportSelection, void, 3, 3, 
               "( String path ) - Export the combined geometry of all selected objects to the specified path in collada format." )
 {  
-   object->colladaExportSelection( argv[2] );
+   object->colladaExportSelection( (const char*)argv[2] );
 }
 
 void WorldEditor::makeSelectionPrefab( const char *filename )

+ 1 - 1
Engine/source/gui/worldEditor/worldEditor.h

@@ -76,7 +76,7 @@ class WorldEditor : public EditTSCtrl
          Point3F p2;
       };
 
-      void ignoreObjClass(U32 argc, const char** argv);
+      void ignoreObjClass(U32 argc, ConsoleValueRef* argv);
       void clearIgnoreList();
 
       static bool setObjectsUseBoxCenter( void *object, const char *index, const char *data ) { static_cast<WorldEditor*>(object)->setObjectsUseBoxCenter( dAtob( data ) ); return false; };

+ 2 - 2
Engine/source/materials/materialManager.cpp

@@ -465,7 +465,7 @@ ConsoleFunction( addMaterialMapping, void, 3, 3, "(string texName, string matNam
    "block or interior surface using the associated texture.\n\n"
    "@ingroup Materials")
 {
-   MATMGR->mapMaterial(argv[1],argv[2]);
+   MATMGR->mapMaterial((const char*)argv[1],(const char*)argv[2]);
 }
 
 ConsoleFunction( getMaterialMapping, const char*, 2, 2, "(string texName)\n"
@@ -474,7 +474,7 @@ ConsoleFunction( getMaterialMapping, const char*, 2, 2, "(string texName)\n"
    "@param texName Name of the texture\n\n"
    "@ingroup Materials")
 {
-   return MATMGR->getMapEntry(argv[1]).c_str();
+   return MATMGR->getMapEntry((const char*)argv[1]).c_str();
 }
 
 ConsoleFunction( dumpMaterialInstances, void, 1, 1, 

+ 1 - 1
Engine/source/sfx/sfxSource.cpp

@@ -316,7 +316,7 @@ void SFXSource::initPersistFields()
 
 //-----------------------------------------------------------------------------
 
-bool SFXSource::processArguments( S32 argc, const char **argv )
+bool SFXSource::processArguments( S32 argc, ConsoleValueRef *argv )
 {
    // Don't allow subclasses of this to be created via script.  Force
    // usage of the SFXSystem functions.

+ 1 - 1
Engine/source/sfx/sfxSource.h

@@ -382,7 +382,7 @@ class SFXSource : public SimGroup
 
       /// We overload this to disable creation of 
       /// a source via script 'new'.
-      virtual bool processArguments( S32 argc, const char **argv );
+      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
       
       // Console getters/setters.
       static bool _setDescription( void *obj, const char *index, const char *data );

+ 1 - 1
Engine/source/sfx/sfxTrack.cpp

@@ -86,7 +86,7 @@ void SFXTrack::initPersistFields()
 
 //-----------------------------------------------------------------------------
 
-bool SFXTrack::processArguments( S32 argc, const char **argv )
+bool SFXTrack::processArguments( S32 argc, ConsoleValueRef *argv )
 {
    if( typeid( *this ) == typeid( SFXTrack ) )
    {

+ 1 - 1
Engine/source/sfx/sfxTrack.h

@@ -57,7 +57,7 @@ class SFXTrack : public SimDataBlock
       StringTableEntry mParameters[ MaxNumParameters ];
    
       /// Overload this to disable direct instantiation of this class via script 'new'.
-      virtual bool processArguments( S32 argc, const char **argv );
+      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
 
    public:
          

+ 5 - 2
Engine/source/sim/actionMap.cpp

@@ -1746,7 +1746,8 @@ static ConsoleDocFragment _ActionMapbind2(
 ConsoleMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier spec, mod...], command )" 
 			  "@hide")
 {
-   return object->processBind( argc - 2, argv + 2, NULL );
+   StringStackWrapper args(argc - 2, argv + 2);
+   return object->processBind( args.count(), args, NULL );
 }
 
 static ConsoleDocFragment _ActionMapbindObj1(
@@ -1801,7 +1802,9 @@ ConsoleMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier spec
         return false;
     }
 
-    return object->processBind( argc - 3, argv + 2, simObject );
+	StringStackWrapper args(argc - 3, argv + 2);
+
+    return object->processBind( args.count(), args, simObject );
 }
 
 //------------------------------------------------------------------------------

+ 3 - 0
Engine/source/sim/netConnection.cpp

@@ -433,6 +433,9 @@ NetConnection::NetConnection()
 
    // Disable starting a new journal recording or playback from here on
    Journal::Disable();
+
+   // jamesu - netAddress is not set
+   dMemset(&mNetAddress, '\0', sizeof(NetAddress));
 }
 
 NetConnection::~NetConnection()

+ 2 - 2
Engine/source/terrain/terrExport.cpp

@@ -141,7 +141,7 @@ ConsoleMethod( TerrainBlock, exportHeightMap, bool, 3, 4, "(string filename, [st
    UTF8 fileName[1024];
    String format = "png";
    if( argc > 3 )
-      format = argv[ 3 ];
+      format = (String)argv[ 3 ];
 
    Con::expandScriptFilename( fileName, sizeof( fileName ), argv[2] );
 
@@ -153,7 +153,7 @@ ConsoleMethod( TerrainBlock, exportLayerMaps, bool, 3, 4, "(string filePrefix, [
    UTF8 filePrefix[1024];
    String format = "png";
    if( argc > 3 )
-      format = argv[3];
+      format = (String)argv[3];
 
    Con::expandScriptFilename( filePrefix, sizeof( filePrefix ), argv[2] );
 

+ 1 - 1
Engine/source/ts/collada/colladaImport.cpp

@@ -145,7 +145,7 @@ ConsoleFunction( enumColladaForImport, bool, 3, 3,
 
    // Check if a cached DTS is available => no need to import the collada file
    // if we can load the DTS instead
-   Torque::Path path(argv[1]);
+   Torque::Path path((const char*)argv[1]);
    if (ColladaShapeLoader::canLoadCachedDTS(path))
       return false;
 

+ 1 - 1
Engine/source/ts/collada/colladaLights.cpp

@@ -162,7 +162,7 @@ ConsoleFunction( loadColladaLights, bool, 2, 4,
    "@ingroup Editors\n"
    "@internal")
 {
-   Torque::Path path(argv[1]);
+   Torque::Path path((const char*)argv[1]);
 
    // Optional group to add the lights to. Create if it does not exist, and use
    // the MissionGroup if not specified.

+ 4 - 4
Engine/source/util/settings.cpp

@@ -488,9 +488,9 @@ ConsoleMethod(Settings, findFirstValue, const char*, 2, 5, "settingObj.findFirst
 	if( argc == 3 )
 		return object->findFirstValue( argv[2] );
 	else if( argc == 4 )
-		return object->findFirstValue( argv[2], argv[3] );
+		return object->findFirstValue( argv[2], dAtob(argv[3]) );
 	else if( argc == 5 )
-		return object->findFirstValue( argv[2], argv[3], argv[4] );
+		return object->findFirstValue( argv[2], dAtob(argv[3]), dAtob(argv[4]) );
 	else
 		return "";
 }
@@ -691,8 +691,8 @@ ConsoleMethod(Settings, remove, void, 3, 4, "settingObj.remove(settingName, incl
 	}
 	else if(argc == 4)
 	{
-		object->remove( argv[2], argv[3] );
-		object->remove( argv[2], argv[3] );
+		object->remove( argv[2], dAtob(argv[3]) );
+		object->remove( argv[2], dAtob(argv[3]) );
 	}
 }
 

+ 1 - 1
Engine/source/util/undo.cpp

@@ -566,7 +566,7 @@ ConsoleMethod( UndoManager, pushCompound, const char*, 2, 3, "( string name=\"\"
 {
    String name;
    if( argc > 2 )
-      name = argv[ 2 ];
+      name = (String)argv[ 2 ];
       
    CompoundUndoAction* action = object->pushCompound( name );
    if( !action )