Kaynağa Gözat

Merge pull request #842 from eightyeight/console-func-refactor

jamesu's console function refactor
Daniel Buckmaster 10 yıl önce
ebeveyn
işleme
81a385094f
94 değiştirilmiş dosya ile 1895 ekleme ve 730 silme
  1. 1 0
      Engine/source/T3D/aiConnection.cpp
  2. 6 3
      Engine/source/T3D/gameBase/gameConnection.cpp
  3. 2 2
      Engine/source/T3D/lightBase.cpp
  4. 1 1
      Engine/source/T3D/missionMarker.cpp
  5. 7 7
      Engine/source/T3D/physics/physicsPlugin.cpp
  6. 11 9
      Engine/source/app/net/net.cpp
  7. 1 1
      Engine/source/app/net/tcpObject.cpp
  8. 1 1
      Engine/source/app/net/tcpObject.h
  9. 11 6
      Engine/source/cinterface/c_scripting.cpp
  10. 12 6
      Engine/source/cinterface/cinterface.cpp
  11. 28 3
      Engine/source/component/dynamicConsoleMethodComponent.cpp
  12. 2 2
      Engine/source/component/dynamicConsoleMethodComponent.h
  13. 5 5
      Engine/source/component/simComponent.cpp
  14. 1 1
      Engine/source/component/simComponent.h
  15. 1 1
      Engine/source/console/ICallMethod.h
  16. 1 1
      Engine/source/console/SimXMLDocument.cpp
  17. 1 1
      Engine/source/console/SimXMLDocument.h
  18. 2 8
      Engine/source/console/arrayObject.cpp
  19. 2 1
      Engine/source/console/ast.h
  20. 46 1
      Engine/source/console/astNodes.cpp
  21. 56 0
      Engine/source/console/codeBlock.cpp
  22. 4 2
      Engine/source/console/codeBlock.h
  23. 235 40
      Engine/source/console/compiledEval.cpp
  24. 11 2
      Engine/source/console/compiler.h
  25. 464 103
      Engine/source/console/console.cpp
  26. 225 33
      Engine/source/console/console.h
  27. 13 8
      Engine/source/console/consoleFunctions.cpp
  28. 111 43
      Engine/source/console/consoleInternal.cpp
  29. 162 212
      Engine/source/console/consoleInternal.h
  30. 1 1
      Engine/source/console/consoleLogger.cpp
  31. 1 1
      Engine/source/console/consoleLogger.h
  32. 86 66
      Engine/source/console/engineAPI.h
  33. 2 2
      Engine/source/console/engineDoc.cpp
  34. 1 1
      Engine/source/console/fieldBrushObject.cpp
  35. 9 9
      Engine/source/console/persistenceManager.cpp
  36. 5 5
      Engine/source/console/sim.cpp
  37. 9 0
      Engine/source/console/sim.h
  38. 22 22
      Engine/source/console/simEvents.cpp
  39. 6 3
      Engine/source/console/simEvents.h
  40. 5 0
      Engine/source/console/simManager.cpp
  41. 1 1
      Engine/source/console/simObject.cpp
  42. 1 1
      Engine/source/console/simObject.h
  43. 1 1
      Engine/source/console/simObjectList.cpp
  44. 2 2
      Engine/source/console/simPersistSet.cpp
  45. 1 1
      Engine/source/console/simPersistSet.h
  46. 8 8
      Engine/source/console/simSet.cpp
  47. 2 2
      Engine/source/console/simSet.h
  48. 166 8
      Engine/source/console/stringStack.cpp
  49. 46 0
      Engine/source/console/stringStack.h
  50. 2 2
      Engine/source/core/fileObject.cpp
  51. 3 3
      Engine/source/environment/editors/guiMeshRoadEditorCtrl.cpp
  52. 3 3
      Engine/source/environment/editors/guiRiverEditorCtrl.cpp
  53. 1 1
      Engine/source/environment/editors/guiRoadEditorCtrl.cpp
  54. 1 1
      Engine/source/environment/waterObject.cpp
  55. 1 1
      Engine/source/environment/waterObject.h
  56. 2 2
      Engine/source/forest/forest.cpp
  57. 1 1
      Engine/source/gui/controls/guiMaterialCtrl.cpp
  58. 3 3
      Engine/source/gui/controls/guiPopUpCtrl.cpp
  59. 3 3
      Engine/source/gui/controls/guiPopUpCtrlEx.cpp
  60. 1 1
      Engine/source/gui/controls/guiTreeViewCtrl.cpp
  61. 3 3
      Engine/source/gui/core/guiCanvas.cpp
  62. 1 1
      Engine/source/gui/core/guiControl.cpp
  63. 1 1
      Engine/source/gui/core/guiControl.h
  64. 5 5
      Engine/source/gui/editor/guiEditCtrl.cpp
  65. 2 3
      Engine/source/gui/editor/guiFilterCtrl.cpp
  66. 3 3
      Engine/source/gui/editor/guiInspector.cpp
  67. 1 1
      Engine/source/gui/editor/guiInspectorTypes.cpp
  68. 1 1
      Engine/source/gui/worldEditor/creator.cpp
  69. 1 1
      Engine/source/gui/worldEditor/editorIconRegistry.cpp
  70. 4 4
      Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp
  71. 1 1
      Engine/source/gui/worldEditor/terrainEditor.cpp
  72. 5 5
      Engine/source/gui/worldEditor/worldEditor.cpp
  73. 1 1
      Engine/source/gui/worldEditor/worldEditor.h
  74. 2 2
      Engine/source/gui/worldEditor/worldEditorSelection.cpp
  75. 1 1
      Engine/source/i18n/i18n.cpp
  76. 3 3
      Engine/source/materials/materialManager.cpp
  77. 2 2
      Engine/source/platformMac/macCarbFileio.mm
  78. 1 1
      Engine/source/platformWin32/winInput.cpp
  79. 1 1
      Engine/source/platformX86UNIX/x86UNIXInput.client.cpp
  80. 1 1
      Engine/source/platformX86UNIX/x86UNIXMath.cpp
  81. 3 3
      Engine/source/postFx/postEffectVis.cpp
  82. 1 1
      Engine/source/sfx/sfxSource.cpp
  83. 1 1
      Engine/source/sfx/sfxSource.h
  84. 3 3
      Engine/source/sfx/sfxSystem.cpp
  85. 1 1
      Engine/source/sfx/sfxTrack.cpp
  86. 1 1
      Engine/source/sfx/sfxTrack.h
  87. 10 8
      Engine/source/sim/actionMap.cpp
  88. 3 0
      Engine/source/sim/netConnection.cpp
  89. 2 2
      Engine/source/terrain/terrExport.cpp
  90. 2 2
      Engine/source/ts/collada/colladaImport.cpp
  91. 2 2
      Engine/source/ts/collada/colladaLights.cpp
  92. 1 1
      Engine/source/util/messaging/eventManager.cpp
  93. 4 4
      Engine/source/util/settings.cpp
  94. 2 2
      Engine/source/util/undo.cpp

+ 1 - 0
Engine/source/T3D/aiConnection.cpp

@@ -147,6 +147,7 @@ ConsoleFunction(aiConnect, S32 , 2, 20, "(...)"
    // Make sure and leav args[1] empty.
    const char* args[21];
    args[0] = "onConnect";
+   args[1] = NULL; // Filled in later
    for (S32 i = 1; i < argc; i++)
       args[i + 1] = argv[i];
 

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

@@ -281,7 +281,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()
@@ -323,6 +324,7 @@ void GameConnection::onConnectionEstablished(bool isInitiator)
 
       const char *argv[MaxConnectArgs + 2];
       argv[0] = "onConnect";
+      argv[1] = NULL; // Filled in later
       for(U32 i = 0; i < mConnectArgc; i++)
          argv[i + 2] = mConnectArgv[i];
       // NOTE: Need to fallback to Con::execute() as IMPLEMENT_CALLBACK does not 
@@ -442,7 +444,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];
@@ -451,6 +453,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;
@@ -974,7 +977,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();
 }

+ 2 - 2
Engine/source/T3D/lightBase.cpp

@@ -439,7 +439,7 @@ ConsoleMethod( LightBase, playAnimation, void, 2, 3, "( [LightAnimData anim] )\t
     LightAnimData *animData;
     if ( !Sim::findObject( argv[2], animData ) )
     {
-        Con::errorf( "LightBase::playAnimation() - Invalid LightAnimData '%s'.", argv[2] );
+        Con::errorf( "LightBase::playAnimation() - Invalid LightAnimData '%s'.", (const char*)argv[2] );
         return;
     }
 
@@ -481,4 +481,4 @@ void LightBase::pauseAnimation( void )
         mAnimState.active = false;
         setMaskBits( UpdateMask );
     }
-}
+}

+ 1 - 1
Engine/source/T3D/missionMarker.cpp

@@ -555,7 +555,7 @@ ConsoleMethod(SpawnSphere, spawnObject, S32, 2, 3,
    String additionalProps;
 
    if (argc == 3)
-      additionalProps = String(argv[2]);
+      additionalProps = (const char*)argv[2];
 
    SimObject* obj = object->spawnObject(additionalProps);
 

+ 7 - 7
Engine/source/T3D/physics/physicsPlugin.cpp

@@ -147,13 +147,13 @@ ConsoleFunction( physicsDestroy, void, 1, 1, "physicsDestroy()" )
 
 ConsoleFunction( physicsInitWorld, bool, 2, 2, "physicsInitWorld( String worldName )" )
 {
-   return PHYSICSMGR && PHYSICSMGR->createWorld( String( argv[1] ) );
+   return PHYSICSMGR && PHYSICSMGR->createWorld( (const char*)argv[1] );
 }
 
 ConsoleFunction( physicsDestroyWorld, void, 2, 2, "physicsDestroyWorld( String worldName )" )
 {
    if ( PHYSICSMGR )
-      PHYSICSMGR->destroyWorld( String( argv[1] ) );
+      PHYSICSMGR->destroyWorld( (const char*)argv[1] );
 }
 
 
@@ -162,13 +162,13 @@ ConsoleFunction( physicsDestroyWorld, void, 2, 2, "physicsDestroyWorld( String w
 ConsoleFunction( physicsStartSimulation, void, 2, 2, "physicsStartSimulation( String worldName )" )
 {
    if ( PHYSICSMGR )
-      PHYSICSMGR->enableSimulation( String( argv[1] ), true );
+      PHYSICSMGR->enableSimulation( (const char*)argv[1], true );
 }
 
 ConsoleFunction( physicsStopSimulation, void, 2, 2, "physicsStopSimulation( String worldName )" )
 {
    if ( PHYSICSMGR )
-      PHYSICSMGR->enableSimulation( String( argv[1] ), false );
+      PHYSICSMGR->enableSimulation( (const char*)argv[1], false );
 }
 
 ConsoleFunction( physicsSimulationEnabled, bool, 1, 1, "physicsSimulationEnabled()" )
@@ -182,7 +182,7 @@ ConsoleFunction( physicsSimulationEnabled, bool, 1, 1, "physicsSimulationEnabled
 ConsoleFunction( physicsSetTimeScale, void, 2, 2, "physicsSetTimeScale( F32 scale )" )
 {
    if ( PHYSICSMGR )
-      PHYSICSMGR->setTimeScale( dAtof( argv[1] ) );
+      PHYSICSMGR->setTimeScale( argv[1] );
 }
 
 // Get the currently set time scale.
@@ -212,5 +212,5 @@ ConsoleFunction( physicsRestoreState, void, 1, 1, "physicsRestoreState()" )
 ConsoleFunction( physicsDebugDraw, void, 2, 2, "physicsDebugDraw( bool enable )" )
 {
    if ( PHYSICSMGR )
-      PHYSICSMGR->enableDebugDraw( dAtoi( argv[1] ) );
-}
+      PHYSICSMGR->enableDebugDraw( (S32)argv[1] );
+}

+ 11 - 9
Engine/source/app/net/net.cpp

@@ -251,7 +251,8 @@ ConsoleFunction( commandToServer, void, 2, RemoteCommandEvent::MaxRemoteCommandA
    NetConnection *conn = NetConnection::getConnectionToServer();
    if(!conn)
       return;
-   RemoteCommandEvent::sendRemoteCommand(conn, argc - 1, argv + 1);
+   StringStackWrapper args(argc - 1, argv + 1);
+   RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
 }
 
 ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandArgs + 2, "(NetConnection client, string func, ...)"
@@ -288,7 +289,8 @@ ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandA
    NetConnection *conn;
    if(!Sim::findObject(argv[1], conn))
       return;
-   RemoteCommandEvent::sendRemoteCommand(conn, argc - 2, argv + 2);
+   StringStackWrapper args(argc - 2, argv + 2);
+   RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
 }
 
 
@@ -304,9 +306,10 @@ DefineEngineFunction(removeTaggedString, void, (S32 tag), (-1),
    "@see addTaggedString()\n"
    "@see getTaggedString()\n"
    "@ingroup Networking\n")
-	{
-	RemoteCommandEvent::removeTaggedString(tag);
-	}
+   {
+   RemoteCommandEvent::removeTaggedString(tag);
+   }
+
 
 DefineEngineFunction(addTaggedString, const char* , (const char* str), (""),
    "@brief Use the addTaggedString function to tag a new string and add it to the NetStringTable\n\n"
@@ -320,10 +323,9 @@ DefineEngineFunction(addTaggedString, const char* , (const char* str), (""),
    "@see removeTaggedString()\n"
    "@see getTaggedString()\n"
    "@ingroup Networking\n")
-	{
-	return RemoteCommandEvent::addTaggedString(str);
-	}
-
+   {
+   return RemoteCommandEvent::addTaggedString(str);
+   }
 
 
 DefineEngineFunction(getTaggedString, const char* , (const char *tag), (""),

+ 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 false;
       }
 
-      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);
    }
 
    S32 script_simobject_get_id(SimObject* so)

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

@@ -267,7 +267,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)
@@ -278,7 +279,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)
@@ -289,7 +291,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);
 	}
 
 
@@ -300,7 +303,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)
@@ -310,7 +314,8 @@ extern "C" {
 		if (!entry)
 			return false;
 
-		return entry->cb.mBoolCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mBoolCallbackFunc(NULL, args.count(), args);
 	}
 
 
@@ -324,7 +329,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 "";

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

@@ -21,6 +21,10 @@
 //-----------------------------------------------------------------------------
 
 #include "component/dynamicConsoleMethodComponent.h"
+#include "console/stringStack.h"
+
+extern StringStack STR;
+extern ConsoleValueStack CSTK;
 
 IMPLEMENT_CO_NETOBJECT_V1(DynamicConsoleMethodComponent);
 
@@ -90,7 +94,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 +123,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 +134,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 );
@@ -150,23 +156,42 @@ const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, const char *ar
          DynamicConsoleMethodComponent *pThisComponent = dynamic_cast<DynamicConsoleMethodComponent*>( pComponent );
          AssertFatal( pThisComponent, "DynamicConsoleMethodComponent::callMethod - Non DynamicConsoleMethodComponent component attempting to callback!");
 
+         // Prevent stack corruption
+         STR.pushFrame();
+         CSTK.pushFrame();
+         // --
+
          // Only call on first depth components
          // Should isMethod check these calls?  [11/22/2006 justind]
          if(pComponent->isEnabled())
             Con::execute( pThisComponent, argc, argv );
 
+         // Prevent stack corruption
+         STR.popFrame();
+         CSTK.popFrame();
+         // --
+
          // Bail if this was the first element
          //if( nItr == componentList.begin() )
          //   break;
       }
       unlockComponentList();
    }
+
+   // Prevent stack corruption
+   STR.pushFrame();
+   CSTK.pushFrame();
+   // --
    
    // Set Owner Field
    const char* result = "";
    if(callThis)
       result = Con::execute( pThis, argc, argv, true ); // true - exec method onThisOnly, not on DCMCs
 
+   // Prevent stack corruption
+   STR.popFrame();
+   CSTK.popFrame();
+   // --
    return result;
 }
 

+ 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, ... );

+ 5 - 5
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++)
    {
@@ -179,7 +179,7 @@ bool SimComponent::processArguments(S32 argc, const char **argv)
       if(obj)
          addComponent(obj);
       else
-         Con::printf("SimComponent::processArguments - Invalid Component Object \"%s\"", argv[i]);
+         Con::printf("SimComponent::processArguments - Invalid Component Object \"%s\"", (const char*)argv[i]);
    }
    return true;
 }
@@ -383,7 +383,7 @@ ConsoleMethod( SimComponent, addComponents, bool, 3, 64, "%obj.addComponents( %c
       if(obj)
          object->addComponent(obj);
       else
-         Con::printf("SimComponent::addComponents - Invalid Component Object \"%s\"", argv[i]);
+         Con::printf("SimComponent::addComponents - Invalid Component Object \"%s\"", (const char*)argv[i]);
    }
    return true;
 }
@@ -399,7 +399,7 @@ ConsoleMethod( SimComponent, removeComponents, bool, 3, 64, "%obj.removeComponen
       if(obj)
          object->removeComponent(obj);
       else
-         Con::printf("SimComponent::removeComponents - Invalid Component Object \"%s\"", argv[i]);
+         Con::printf("SimComponent::removeComponents - Invalid Component Object \"%s\"", (const char*)argv[i]);
    }
    return true;
 }
@@ -449,4 +449,4 @@ ConsoleMethod(SimComponent, getIsTemplate, bool, 2, 2, "() Check whether SimComp
 			  "@return true if is a template and false if not")
 {
    return object->getIsTemplate();
-}
+}

+ 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();

+ 2 - 8
Engine/source/console/arrayObject.cpp

@@ -103,10 +103,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
    ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
    ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
    
-   const char* argv[ 3 ];
-   argv[ 0 ] = smCompareFunction;
-   argv[ 1 ] = ea->key;
-   argv[ 2 ] = eb->key;
+   ConsoleValueRef argv[] = { smCompareFunction, ea->key, eb->key }; 
    
    S32 result = dAtoi( Con::execute( 3, argv ) );
    S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
@@ -118,10 +115,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void
    ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
    ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
    
-   const char* argv[ 3 ];
-   argv[ 0 ] = smCompareFunction;
-   argv[ 1 ] = ea->value;
-   argv[ 2 ] = eb->value;
+   ConsoleValueRef argv[] = { smCompareFunction, ea->value, eb->value }; 
    
    S32 result = dAtoi( Con::execute( 3, argv ) );
    S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );

+ 2 - 1
Engine/source/console/ast.h

@@ -39,7 +39,8 @@ enum TypeReq
    TypeReqNone,
    TypeReqUInt,
    TypeReqFloat,
-   TypeReqString
+   TypeReqString,
+   TypeReqVar
 };
 
 /// Representation of a node for the scripting language parser.

+ 46 - 1
Engine/source/console/astNodes.cpp

@@ -106,6 +106,8 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
          return OP_STR_TO_FLT;
       case TypeReqNone:
          return OP_STR_TO_NONE;
+      case TypeReqVar:
+         return OP_SAVEVAR_STR;
       default:
          break;
       }
@@ -120,6 +122,8 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
          return OP_FLT_TO_STR;
       case TypeReqNone:
          return OP_FLT_TO_NONE;
+      case TypeReqVar:
+         return OP_SAVEVAR_FLT;
       default:
          break;
       }
@@ -134,6 +138,24 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
          return OP_UINT_TO_STR;
       case TypeReqNone:
          return OP_UINT_TO_NONE;
+      case TypeReqVar:
+         return OP_SAVEVAR_UINT;
+      default:
+         break;
+      }
+   }
+   else if(src == TypeReqVar)
+   {
+      switch(dst)
+      {
+      case TypeReqUInt:
+         return OP_LOADVAR_UINT;
+      case TypeReqFloat:
+         return OP_LOADVAR_FLT;
+      case TypeReqString:
+         return OP_LOADVAR_STR;
+      case TypeReqNone:
+         return OP_COPYVAR_TO_NONE;
       default:
          break;
       }
@@ -698,8 +720,13 @@ U32 VarNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
    case TypeReqString:
       codeStream.emit(OP_LOADVAR_STR);
       break;
+   case TypeReqVar:
+      codeStream.emit(OP_LOADVAR_VAR);
+      break;
    case TypeReqNone:
       break;
+   default:
+      break;
    }
    return codeStream.tell();
 }
@@ -881,7 +908,20 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
    if(subType == TypeReqNone)
       subType = type;
    if(subType == TypeReqNone)
-      subType = TypeReqString;
+   {
+      // What we need to do in this case is turn it into a VarNode reference. 
+      // Unfortunately other nodes such as field access (SlotAccessNode) 
+      // cannot be optimized in the same manner as all fields are exposed 
+      // and set as strings.
+      if (dynamic_cast<VarNode*>(expr) != NULL)
+      {
+         subType = TypeReqVar;
+      }
+      else
+      {
+         subType = TypeReqString;
+      }
+   }
    // if it's an array expr, the formula is:
    // eval expr
    // (push and pop if it's TypeReqString) OP_ADVANCE_STR
@@ -903,6 +943,7 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
    precompileIdent(varName);
    
    ip = expr->compile(codeStream, ip, subType);
+
    if(arrayIndex)
    {
       if(subType == TypeReqString)
@@ -934,6 +975,9 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
    case TypeReqFloat:
       codeStream.emit(OP_SAVEVAR_FLT);
       break;
+   case TypeReqVar:
+      codeStream.emit(OP_SAVEVAR_VAR);
+      break;
    case TypeReqNone:
       break;
    }
@@ -1392,6 +1436,7 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root)
    // OP_FINISH_OBJECT <-- fail point jumps to this opcode
    
    codeStream.emit(OP_PUSH_FRAME);
+
    ip = classNameExpr->compile(codeStream, ip, TypeReqString);
    codeStream.emit(OP_PUSH);
 

+ 56 - 0
Engine/source/console/codeBlock.cpp

@@ -832,6 +832,26 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
             break;
          }
 
+         case OP_RETURN_UINT:
+         {
+            Con::printf( "%i: OP_RETURNUINT", ip - 1 );
+
+            if( upToReturn )
+               return;
+
+            break;
+         }
+
+         case OP_RETURN_FLT:
+         {
+            Con::printf( "%i: OP_RETURNFLT", ip - 1 );
+
+            if( upToReturn )
+               return;
+
+            break;
+         }
+
          case OP_CMPEQ:
          {
             Con::printf( "%i: OP_CMPEQ", ip - 1 );
@@ -1012,6 +1032,12 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
             break;
          }
 
+         case OP_LOADVAR_VAR:
+         {
+            Con::printf( "%i: OP_LOADVAR_VAR", ip - 1 );
+            break;
+         }
+
          case OP_SAVEVAR_UINT:
          {
             Con::printf( "%i: OP_SAVEVAR_UINT", ip - 1 );
@@ -1030,6 +1056,12 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
             break;
          }
 
+         case OP_SAVEVAR_VAR:
+         {
+            Con::printf( "%i: OP_SAVEVAR_VAR", ip - 1 );
+            break;
+         }
+
          case OP_SETCUROBJECT:
          {
             Con::printf( "%i: OP_SETCUROBJECT", ip - 1 );
@@ -1161,6 +1193,12 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
             break;
          }
 
+         case OP_COPYVAR_TO_NONE:
+         {
+            Con::printf( "%i: OP_COPYVAR_TO_NONE", ip - 1 );
+            break;
+         }
+
          case OP_LOADIMMED_UINT:
          {
             U32 val = code[ ip ];
@@ -1287,6 +1325,24 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
             break;
          }
 
+         case OP_PUSH_UINT:
+         {
+            Con::printf( "%i: OP_PUSH_UINT", ip - 1 );
+            break;
+         }
+
+         case OP_PUSH_FLT:
+         {
+            Con::printf( "%i: OP_PUSH_FLT", ip - 1 );
+            break;
+         }
+
+         case OP_PUSH_VAR:
+         {
+            Con::printf( "%i: OP_PUSH_VAR", ip - 1 );
+            break;
+         }
+
          case OP_PUSH_FRAME:
          {
             Con::printf( "%i: OP_PUSH_FRAME", ip - 1 );

+ 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.
 ///
@@ -145,8 +147,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);
 };
 

+ 235 - 40
Engine/source/console/compiledEval.cpp

@@ -105,7 +105,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.
@@ -191,18 +195,16 @@ namespace Con
       return STR.getArgBuffer(bufferSize);
    }
 
-   char *getFloatArg(F64 arg)
+   ConsoleValueRef getFloatArg(F64 arg)
    {
-      char *ret = STR.getArgBuffer(32);
-      dSprintf(ret, 32, "%g", arg);
-      return ret;
+      ConsoleValueRef ref = arg;
+      return ref;
    }
 
-   char *getIntArg(S32 arg)
+   ConsoleValueRef getIntArg(S32 arg)
    {
-      char *ret = STR.getArgBuffer(32);
-      dSprintf(ret, 32, "%d", arg);
-      return ret;
+      ConsoleValueRef ref = arg;
+      return ref;
    }
    
    char *getStringArg( const char *arg )
@@ -284,6 +286,25 @@ inline void ExprEvalState::setStringVariable(const char *val)
    currentVariable->setStringValue(val);
 }
 
+inline void ExprEvalState::setCopyVariable()
+{
+   if (copyVariable)
+   {
+      switch (copyVariable->value.type)
+      {
+         case ConsoleValue::TypeInternalInt:
+            currentVariable->setIntValue(copyVariable->getIntValue());
+         break;
+         case ConsoleValue::TypeInternalFloat:
+            currentVariable->setFloatValue(copyVariable->getFloatValue());
+         break;
+         default:
+            currentVariable->setStringValue(copyVariable->getStringValue());
+         break;
+	   }
+   }
+}
+
 //------------------------------------------------------------
 
 // Gets a component of an object's field value or a variable and returns it
@@ -404,14 +425,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;
 
@@ -427,7 +449,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
       // assume this points into a function decl:
       U32 fnArgc = code[ip + 2 + 6];
       thisFunctionName = CodeToSTE(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;
@@ -459,11 +481,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 = CodeToSTE(code, ip + (2 + 6 + 1) + (i * 2));
          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 * 2) + (2 + 6 + 1);
       curFloatTable = functionFloats;
@@ -500,6 +533,10 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
       }
    }
 
+   // Reset the console stack frame which at this point will contain 
+   // either nothing or argv[] which we just copied
+   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();
@@ -533,7 +570,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];
@@ -546,6 +583,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.
@@ -618,8 +659,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...");
 
@@ -641,6 +682,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;
                }
 
@@ -662,18 +704,19 @@ breakContinue:
                   break;
                }
 
-               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;
                      }
 
@@ -691,13 +734,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 )
                      {
@@ -726,6 +785,7 @@ breakContinue:
                               getFileLine(ip), newName.c_str() );
                            ip = failJump;
                            STR.popFrame();
+                           CSTK.popFrame();
                            break;
                         }
                         else
@@ -737,6 +797,7 @@ breakContinue:
                            getFileLine(ip), objectName);
                         ip = failJump;
                         STR.popFrame();
+                        CSTK.popFrame();
                         break;
                      }
                   }
@@ -744,16 +805,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;
                }
@@ -769,7 +831,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;
@@ -783,7 +845,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;
@@ -810,7 +872,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;
 
@@ -833,15 +895,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)
                {
@@ -866,6 +943,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)
             {
@@ -889,6 +971,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;
                }
             }
@@ -897,6 +983,8 @@ breakContinue:
             SimDataBlock *dataBlock = dynamic_cast<SimDataBlock *>(currentNewObject);
             static String errorStr;
 
+
+
             // If so, preload it.
             if(dataBlock && !dataBlock->preload(true, errorStr))
             {
@@ -904,6 +992,11 @@ breakContinue:
                            currentNewObject->getName(), errorStr.c_str());
                dataBlock->deleteObject();
                ip = failJump;
+			   
+               // Prevent stack value corruption
+               CSTK.popFrame();
+               STR.popFrame();
+               // --
                break;
             }
 
@@ -958,6 +1051,10 @@ breakContinue:
             else
                intStack[++_UINT] = currentNewObject->getId();
 
+            // Prevent stack value corruption
+            CSTK.popFrame();
+            STR.popFrame();
+            // --
             break;
          }
 
@@ -1040,6 +1137,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 )
             {
@@ -1050,10 +1170,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;
             
@@ -1196,7 +1333,7 @@ breakContinue:
             var = CodeToSTE(code, ip);
             ip += 2;
 
-			// See OP_SETCURVAR
+            // See OP_SETCURVAR
             prevField = NULL;
             prevObject = NULL;
             curObject = NULL;
@@ -1253,6 +1390,11 @@ breakContinue:
             STR.setStringValue(val);
             break;
 
+         case OP_LOADVAR_VAR:
+            // Sets current source of OP_SAVEVAR_VAR
+            gEvalState.copyVariable = gEvalState.currentVariable;
+            break;
+
          case OP_SAVEVAR_UINT:
             gEvalState.setIntVariable(intStack[_UINT]);
             break;
@@ -1264,6 +1406,11 @@ breakContinue:
          case OP_SAVEVAR_STR:
             gEvalState.setStringVariable(STR.getStringValue());
             break;
+		    
+         case OP_SAVEVAR_VAR:
+            // this basically handles %var1 = %var2
+            gEvalState.setCopyVariable();
+            break;
 
          case OP_SETCUROBJECT:
             // Save the previous object for parsing vector fields.
@@ -1451,6 +1598,10 @@ breakContinue:
             _UINT--;
             break;
 
+         case OP_COPYVAR_TO_NONE:
+            gEvalState.copyVariable = NULL;
+            break;
+
          case OP_LOADIMMED_UINT:
             intStack[_UINT+1] = code[ip++];
             _UINT++;
@@ -1527,6 +1678,7 @@ breakContinue:
                   getFileLine(ip-7), fnNamespace ? fnNamespace : "",
                   fnNamespace ? "::" : "", fnName);
                STR.popFrame();
+               CSTK.popFrame();
                break;
             }
             
@@ -1562,7 +1714,7 @@ breakContinue:
             U32 callType = code[ip+4];
 
             ip += 5;
-            STR.getArgcArgv(fnName, &callArgc, &callArgv);
+            CSTK.getArgcArgv(fnName, &callArgc, &callArgv);
 
             const char *componentReturnValue = "";
 
@@ -1586,14 +1738,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();
                   STR.setStringValue("");
                   break;
                }
@@ -1650,6 +1803,7 @@ breakContinue:
                   }
                }
                STR.popFrame();
+               CSTK.popFrame();
 
                if( routingId == MethodOnComponent )
                   STR.setStringValue( componentReturnValue );
@@ -1660,12 +1814,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);
+               // 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
             {
@@ -1686,6 +1858,7 @@ breakContinue:
                      callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs);
                   Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-6), nsEntry->mUsage);
                   STR.popFrame();
+                  CSTK.popFrame();
                }
                else
                {
@@ -1695,16 +1868,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++;
@@ -1727,6 +1902,7 @@ breakContinue:
                      {
                         F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
                         STR.popFrame();
+                        CSTK.popFrame();
                         if(code[ip] == OP_STR_TO_UINT)
                         {
                            ip++;
@@ -1751,12 +1927,14 @@ breakContinue:
                            Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-6), 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++;
@@ -1811,10 +1989,26 @@ breakContinue:
             break;
          case OP_PUSH:
             STR.push();
+            CSTK.pushString(STR.getPreviousStringValue());
+            break;
+         case OP_PUSH_UINT:
+            CSTK.pushUINT(intStack[_UINT]);
+            _UINT--;
+            break;
+         case OP_PUSH_FLT:
+            CSTK.pushFLT(floatStack[_FLT]);
+            _FLT--;
+            break;
+         case OP_PUSH_VAR:
+            if (gEvalState.currentVariable)
+               CSTK.pushValue(gEvalState.currentVariable->value);
+            else
+               CSTK.pushString("");
             break;
 
          case OP_PUSH_FRAME:
             STR.pushFrame();
+            CSTK.pushFrame();
             break;
 
          case OP_ASSERT:
@@ -2044,7 +2238,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;
 }
 
 //------------------------------------------------------------

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

@@ -63,6 +63,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,
@@ -96,10 +99,12 @@ namespace Compiler
       OP_LOADVAR_UINT,// 40
       OP_LOADVAR_FLT,
       OP_LOADVAR_STR,
+      OP_LOADVAR_VAR,
 
       OP_SAVEVAR_UINT,
       OP_SAVEVAR_FLT,
       OP_SAVEVAR_STR,
+      OP_SAVEVAR_VAR,
 
       OP_SETCUROBJECT,
       OP_SETCUROBJECT_NEW,
@@ -126,6 +131,7 @@ namespace Compiler
       OP_UINT_TO_FLT,
       OP_UINT_TO_STR,
       OP_UINT_TO_NONE,
+      OP_COPYVAR_TO_NONE,
 
       OP_LOADIMMED_UINT,
       OP_LOADIMMED_FLT,
@@ -145,8 +151,11 @@ namespace Compiler
       OP_TERMINATE_REWIND_STR,  // 80
       OP_COMPARE_STR,
 
-      OP_PUSH,
-      OP_PUSH_FRAME,
+      OP_PUSH,          // String
+      OP_PUSH_UINT,     // Integer
+      OP_PUSH_FLT,      // Float
+      OP_PUSH_VAR,      // Variable
+      OP_PUSH_FRAME,    // Frame
 
       OP_ASSERT,
       OP_BREAK,

+ 464 - 103
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,72 @@ 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 +817,57 @@ 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 +918,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 +955,21 @@ 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 +981,45 @@ 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 +1164,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())
@@ -1044,10 +1176,11 @@ const char *execute(S32 argc, const char *argv[])
 
       if(!ent)
       {
-         warnf(ConsoleLogEntry::Script, "%s: Unknown command.", argv[0]);
+         warnf(ConsoleLogEntry::Script, "%s: Unknown command.", (const char*)argv[0]);
 
          // Clean up arg buffers, if any.
          STR.clearFunctionOffset();
+         CSTK.resetFrame();
          return "";
       }
       return ent->execute(argc, argv, &gEvalState);
@@ -1064,10 +1197,15 @@ 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];
    if(argc < 2)
       return "";
 
@@ -1078,13 +1216,21 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
    {
       ICallMethod *com = dynamic_cast<ICallMethod *>(object);
       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);
@@ -1095,13 +1241,12 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
 
          // Clean up arg buffers, if any.
          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,90 +1254,62 @@ 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;
    }
-   warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), argv[0]);
+   warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), (const char*)argv[0]);
    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);
+}
+
+#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
 
 
@@ -1390,10 +1507,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));
 }
 
 //------------------------------------------------------------------------------
@@ -1456,3 +1573,247 @@ 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(U32 newValue) : value(NULL)
+{
+   *this = newValue;
+}
+
+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;
+}
+
+S32 ConsoleValue::getSignedIntValue()
+{
+   if(type <= TypeInternalString)
+      return (S32)fval;
+   else
+      return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
+}
+
+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);
+}
+
+bool ConsoleValue::getBoolValue()
+{
+   if(type == TypeInternalString || type == TypeInternalStackString)
+      return dAtob(sval);
+   if(type == TypeInternalFloat)
+      return fval > 0;
+   else if(type == TypeInternalInt)
+      return ival > 0;
+   else {
+      const char *value = Con::getData(type, dataPtr, 0, enumTable);
+      return dAtob(value);
+   }
+}
+
+void ConsoleValue::setIntValue(S32 val)
+{
+   setFloatValue(val);
+}
+
+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::setBoolValue(bool val)
+{
+   return setIntValue(val ? 1 : 0);
+}
+
+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.pushFLT(newValue);
+   stringStackValue = NULL;
+   return *this;
+}
+
+ConsoleValueRef& ConsoleValueRef::operator=(U32 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();
+	}
+}

+ 225 - 33
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,185 @@ 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();
+   S32 getSignedIntValue();
+   F32 getFloatValue();
+   const char *getStringValue();
+   bool getBoolValue();
+   
+   void setIntValue(U32 val);
+   void setIntValue(S32 val);
+   void setFloatValue(F32 val);
+   void setStringValue(const char *value);
+   void setStackStringValue(const char *value);
+   void setBoolValue(bool val);
+   
+   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(U32 value);
+   ConsoleValueRef(S32 value);
+   ConsoleValueRef(F32 value);
+   ConsoleValueRef(F64 value);
+
+   const char *getStringValue() { return value ? value->getStringValue() : ""; }
+   const char *getStringArgValue();
+
+   inline U32 getIntValue() { return value ? value->getIntValue() : 0; }
+   inline S32 getSignedIntValue() { return value ? value->getSignedIntValue() : 0; }
+   inline F32 getFloatValue() { return value ? value->getFloatValue() : 0.0f; }
+   inline bool getBoolValue() { return value ? value->getBoolValue() : false; }
+
+   inline operator const char*() { return getStringValue(); }
+   inline operator String() { return String(getStringValue()); }
+   inline operator U32() { return getIntValue(); }
+   inline operator S32() { return getSignedIntValue(); }
+   inline operator F32() { return getFloatValue(); }
+
+   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=(U32 newValue);
+   ConsoleValueRef& operator=(S32 newValue);
+   ConsoleValueRef& operator=(F32 newValue);
+   ConsoleValueRef& operator=(F64 newValue);
+};
+
+// Overrides to allow ConsoleValueRefs to be directly converted to S32&F32
+
+inline S32 dAtoi(ConsoleValueRef &ref)
+{
+   return ref.getSignedIntValue();
+}
+
+inline F32 dAtof(ConsoleValueRef &ref)
+{
+   return ref.getFloatValue();
+}
+
+inline bool dAtob(ConsoleValue &ref)
+{
+   return ref.getBoolValue();
+}
+
+
+// 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 +311,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);
 /// @}
@@ -183,7 +365,8 @@ namespace Con
       /// 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
       /// 09/07/14 - jamesu - 46->47 64bit support
-      DSOVersion = 47,
+      /// 10/14/14 - jamesu - 47->48 Added opcodes to reduce reliance on strings in function calls
+      DSOVersion = 48,
 
       MaxLineLength = 512,  ///< Maximum length of a line of console input.
       MaxDataTypes = 256    ///< Maximum number of registered data types.
@@ -416,6 +599,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);
 
@@ -566,9 +754,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);
@@ -581,7 +771,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)
@@ -595,9 +784,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);
@@ -641,12 +831,14 @@ namespace Con
    char* getReturnBuffer( const StringBuilder& str );
 
    char* getArgBuffer(U32 bufferSize);
-   char* getFloatArg(F64 arg);
-   char* getIntArg  (S32 arg);
+   ConsoleValueRef getFloatArg(F64 arg);
+   ConsoleValueRef getIntArg  (S32 arg);
    char* getStringArg( const char *arg );
    char* getStringArg( const String& arg );
    /// @}
 
+   void resetStackFrame();
+
    /// @name Namespaces
    /// @{
 
@@ -942,14 +1134,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)
@@ -962,22 +1154,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)
@@ -1000,32 +1192,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 )
 

+ 13 - 8
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);
@@ -2382,7 +2387,7 @@ ConsoleFunction(isDefined, bool, 2, 3, "(string varName)"
       if (dStrcmp(argv[1], "0") && dStrcmp(argv[1], "") && (Sim::findObject(argv[1]) != NULL))
          return true;
       else if (argc > 2)
-         Con::errorf("%s() - can't assign a value to a variable of the form \"%s\"", __FUNCTION__, argv[1]);
+         Con::errorf("%s() - can't assign a value to a variable of the form \"%s\"", __FUNCTION__, (const char*)argv[1]);
    }
 
    return false;
@@ -2417,7 +2422,7 @@ ConsoleFunction( pushInstantGroup, void, 1, 2, "([group])"
 				"@internal")
 {
    if( argc > 1 )
-      Con::pushInstantGroup( argv[ 1 ] );
+      Con::pushInstantGroup( (const char*)argv[ 1 ] );
    else
       Con::pushInstantGroup();
 }
@@ -2437,7 +2442,7 @@ ConsoleFunction(getPrefsPath, const char *, 1, 2, "([relativeFileName])"
 				"@note Appears to be useless in Torque 3D, should be deprecated\n"
 				"@internal")
 {
-   const char *filename = Platform::getPrefsPath(argc > 1 ? argv[1] : NULL);
+   const char *filename = Platform::getPrefsPath(argc > 1 ? (const char*)argv[1] : NULL);
    if(filename == NULL || *filename == 0)
       return "";
      

+ 111 - 43
Engine/source/console/consoleInternal.cpp

@@ -34,7 +34,6 @@
 
 //#define DEBUG_SPEW
 
-
 #define ST_INIT_SIZE 15
 
 static char scratchBuffer[1024];
@@ -168,13 +167,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 +227,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,6 +283,7 @@ 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 )
@@ -307,7 +307,7 @@ 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;
             
             entry->nextEntry = newTableData[ index ];
             newTableData[ index ] = entry;
@@ -330,7 +330,7 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name)
 
    ret = hashTable->mChunker.alloc();
    constructInPlace( ret, name );
-   S32 idx = HashPointer(name) % hashTable->size;
+   U32 idx = HashPointer(name) % hashTable->size;
    ret->nextEntry = hashTable->data[idx];
    hashTable->data[idx] = ret;
    
@@ -454,7 +454,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 +462,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 +492,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 +510,16 @@ 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 +538,92 @@ 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 +650,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;
 }
@@ -616,7 +684,7 @@ void Dictionary::addVariableNotify( const char *name, const Con::NotifyDelegate
     return;
 
    if ( !ent->notify )
-    ent->notify = new Entry::NotifySignal();
+      ent->notify = new Entry::NotifySignal();
 
    ent->notify->notify( callback );
 }
@@ -1268,7 +1336,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)
    {

+ 162 - 212
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,74 +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.
-
-      friend class Dictionary;
-
-      #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)
@@ -383,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 )
@@ -413,159 +359,163 @@ 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
+   {
+      Dictionary* owner;
+      S32 size;
+      S32 count;
+      Entry **data;
+      FreeListChunker< Entry > mChunker;
+     
+      HashTableData( Dictionary* owner )
+         : owner( owner ), size( 0 ), count( 0 ), data( NULL ) {}
    };
 
-    struct HashTableData
-    {
-        Dictionary* owner;
-        S32 size;
-        S32 count;
-        Entry **data;
-        FreeListChunker< Entry > mChunker;
-        
-        HashTableData( Dictionary* owner )
-           : owner( owner ), size( 0 ), count( 0 ), data( NULL ) {}
-    };
-
-    HashTableData* hashTable;
-    HashTableData ownHashTable;
-    ExprEvalState *exprState;
-    
-    StringTableEntry scopeName;
-    Namespace *scopeNamespace;
-    CodeBlock *code;
-    U32 ip;
-
-    Dictionary();
-    ~Dictionary();
-
-    Entry *lookup(StringTableEntry name);
-    Entry *add(StringTableEntry name);
-    void setState(ExprEvalState *state, Dictionary* ref=NULL);
-    void remove(Entry *);
-    void reset();
-
-    void exportVariables( const char *varString, const char *fileName, bool append );
-    void exportVariables( const char *varString, Vector<String> *names, Vector<String> *values );
-    void deleteVariables( const char *varString );
-
-    void setVariable(StringTableEntry name, const char *value);
-    const char *getVariable(StringTableEntry name, bool *valid = NULL);
-    
-    U32 getCount() const
-    {
+   HashTableData* hashTable;
+   HashTableData ownHashTable;
+   ExprEvalState *exprState;
+
+   StringTableEntry scopeName;
+   Namespace *scopeNamespace;
+   CodeBlock *code;
+   U32 ip;
+
+   Dictionary();
+   ~Dictionary();
+
+   Entry *lookup(StringTableEntry name);
+   Entry *add(StringTableEntry name);
+   void setState(ExprEvalState *state, Dictionary* ref=NULL);
+   void remove(Entry *);
+   void reset();
+
+   void exportVariables( const char *varString, const char *fileName, bool append );
+   void exportVariables( const char *varString, Vector<String> *names, Vector<String> *values );
+   void deleteVariables( const char *varString );
+
+   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
+   {
       return hashTable->count;
-    }
-    bool isOwner() const
-    {
+   }
+   bool isOwner() const
+   {
       return hashTable->owner;
-    }
+   }
+
+   /// @see Con::addVariable
+   Entry* addVariable(  const char *name, 
+                        S32 type, 
+                        void *dataPtr, 
+                        const char* usage );
 
-    /// @see Con::addVariable
-    Entry* addVariable(    const char *name, 
-                           S32 type, 
-                           void *dataPtr, 
-                           const char* usage );
+   /// @see Con::removeVariable
+   bool removeVariable(StringTableEntry name);
 
-    /// @see Con::removeVariable
-    bool removeVariable(StringTableEntry name);
+   /// @see Con::addVariableNotify
+   void addVariableNotify( const char *name, const Con::NotifyDelegate &callback );
 
-    /// @see Con::addVariableNotify
-    void addVariableNotify( const char *name, const Con::NotifyDelegate &callback );
+   /// @see Con::removeVariableNotify
+   void removeVariableNotify( const char *name, const Con::NotifyDelegate &callback );
 
-    /// @see Con::removeVariableNotify
-    void removeVariableNotify( const char *name, const Con::NotifyDelegate &callback );
+   /// Return the best tab completion for prevText, with the length
+   /// of the pre-tab string in baseLen.
+   const char *tabComplete(const char *prevText, S32 baseLen, bool);
 
-    /// Return the best tab completion for prevText, with the length
-    /// of the pre-tab string in baseLen.
-    const char *tabComplete(const char *prevText, S32 baseLen, bool);
-    
-    /// Run integrity checks for debugging.
-    void validate();
+   /// Run integrity checks for debugging.
+   void validate();
 };
 
 class ExprEvalState
 {
 public:
-    /// @name Expression Evaluation
-    /// @{
-
-    ///
-    SimObject *thisObject;
-    Dictionary::Entry *currentVariable;
-    bool traceOn;
-    
-    U32 mStackDepth;
-
-    ExprEvalState();
-    ~ExprEvalState();
-
-    /// @}
-
-    /// @name Stack Management
-    /// @{
-
-    /// The stack of callframes.  The extra redirection is necessary since Dictionary holds
-    /// an interior pointer that will become invalid when the object changes address.
-    Vector< Dictionary* > stack;
-
-    ///
-    Dictionary globalVars;
-    
-    void setCurVarName(StringTableEntry name);
-    void setCurVarNameCreate(StringTableEntry name);
-    S32 getIntVariable();
-    F64 getFloatVariable();
-    const char *getStringVariable();
-    void setIntVariable(S32 val);
-    void setFloatVariable(F64 val);
-    void setStringVariable(const char *str);
-
-    void pushFrame(StringTableEntry frameName, Namespace *ns);
-    void popFrame();
-
-    /// Puts a reference to an existing stack frame
-    /// on the top of the stack.
-    void pushFrameRef(S32 stackIndex);
-    
-    U32 getStackDepth() const
-    {
-       return mStackDepth;
-    }
-    
-    Dictionary& getCurrentFrame()
-    {
+   /// @name Expression Evaluation
+   /// @{
+
+   ///
+   SimObject *thisObject;
+   Dictionary::Entry *currentVariable;
+   Dictionary::Entry *copyVariable;
+   bool traceOn;
+
+   U32 mStackDepth;
+
+   ExprEvalState();
+   ~ExprEvalState();
+
+   /// @}
+
+   /// @name Stack Management
+   /// @{
+
+   /// The stack of callframes.  The extra redirection is necessary since Dictionary holds
+   /// an interior pointer that will become invalid when the object changes address.
+   Vector< Dictionary* > stack;
+
+   ///
+   Dictionary globalVars;
+
+   void setCurVarName(StringTableEntry name);
+   void setCurVarNameCreate(StringTableEntry name);
+
+   S32 getIntVariable();
+   F64 getFloatVariable();
+   const char *getStringVariable();
+   void setIntVariable(S32 val);
+   void setFloatVariable(F64 val);
+   void setStringVariable(const char *str);
+   void setCopyVariable();
+
+   void pushFrame(StringTableEntry frameName, Namespace *ns);
+   void popFrame();
+
+   /// Puts a reference to an existing stack frame
+   /// on the top of the stack.
+   void pushFrameRef(S32 stackIndex);
+ 
+   U32 getStackDepth() const
+   {
+      return mStackDepth;
+   }
+ 
+   Dictionary& getCurrentFrame()
+   {
       return *( stack[ mStackDepth - 1 ] );
-    }
+   }
+
+   /// @}
 
-    /// @}
-    
-    /// Run integrity checks for debugging.
-    void validate();
+   /// Run integrity checks for debugging.
+   void validate();
 };
 
 namespace Con

+ 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();

+ 86 - 66
Engine/source/console/engineAPI.h

@@ -146,12 +146,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";
@@ -159,33 +159,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 );
+   argv[ argc ] = 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 );
+   argv[ argc ] = 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 ++;
@@ -208,6 +208,11 @@ struct EngineUnmarshallData
 template<>
 struct EngineUnmarshallData< S32 >
 {
+   S32 operator()( ConsoleValueRef &ref ) const
+   {
+      return (S32)ref;
+   }
+
    S32 operator()( const char* str ) const
    {
       return dAtoi( str );
@@ -216,6 +221,11 @@ struct EngineUnmarshallData< S32 >
 template<>
 struct EngineUnmarshallData< U32 >
 {
+   U32 operator()( ConsoleValueRef &ref ) const
+   {
+      return (U32)((S32)ref);
+   }
+
    U32 operator()( const char* str ) const
    {
       return dAtoui( str );
@@ -224,6 +234,11 @@ struct EngineUnmarshallData< U32 >
 template<>
 struct EngineUnmarshallData< F32 >
 {
+   F32 operator()( ConsoleValueRef &ref ) const
+   {
+      return (F32)ref;
+   }
+
    F32 operator()( const char* str ) const
    {
       return dAtof( str );
@@ -1392,12 +1407,12 @@ struct _EngineConsoleThunk< startArgc, R() >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 )() );
    }
@@ -1407,12 +1422,12 @@ struct _EngineConsoleThunk< startArgc, void() >
 {
    typedef void ReturnType;
    static const S32 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 )();
    }
@@ -1423,13 +1438,13 @@ struct _EngineConsoleThunk< startArgc, R( A ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1440,13 +1455,13 @@ struct _EngineConsoleThunk< startArgc, void( A ) >
 {
    typedef void ReturnType;
    static const S32 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 );
@@ -1458,14 +1473,14 @@ struct _EngineConsoleThunk< startArgc, R( A, B ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1477,14 +1492,14 @@ struct _EngineConsoleThunk< startArgc, void( A, B ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1497,7 +1512,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1505,7 +1520,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 ) );
@@ -1518,7 +1533,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1526,7 +1541,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 ) );
@@ -1540,7 +1555,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1549,7 +1564,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 ) );
@@ -1563,7 +1578,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1572,7 +1587,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 ) );
@@ -1587,7 +1602,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1597,7 +1612,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 ) );
@@ -1612,7 +1627,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1622,7 +1637,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 ) );
@@ -1638,7 +1653,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1649,7 +1664,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 ) );
@@ -1665,7 +1680,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1676,7 +1691,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 ) );
@@ -1693,7 +1708,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1705,7 +1720,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 ) );
@@ -1722,7 +1737,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1734,7 +1749,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 ) );
@@ -1752,7 +1767,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1765,7 +1780,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 ) );
@@ -1783,7 +1798,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1796,7 +1811,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 ) );
@@ -1815,7 +1830,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1829,7 +1844,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 ) );
@@ -1848,7 +1863,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1862,7 +1877,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 ) );
@@ -1882,7 +1897,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1897,7 +1912,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 ) );
@@ -1917,7 +1932,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -1932,7 +1947,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 ) );
@@ -1952,7 +1967,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) >
 {
    typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
    static const S32 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 ) );
@@ -1968,7 +1983,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 ) );
@@ -1989,7 +2004,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
 {
    typedef void ReturnType;
    static const S32 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 ) );
@@ -2005,7 +2020,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 ) );
@@ -2089,7 +2104,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                                                            \
@@ -2169,7 +2184,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 );                                                                                       \
@@ -2226,7 +2241,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                                        \
@@ -2250,7 +2265,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                                                            \
@@ -2275,7 +2290,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 );                                                                                       \
@@ -2297,7 +2312,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                                        \
@@ -2620,14 +2635,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(); // 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 );

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

@@ -383,7 +383,7 @@ ConsoleMethod(FieldBrushObject, copyFields, void, 3, 4, "(simObject, [fieldList]
     }
 
     // Fetch field list.
-    const char* pFieldList = (argc > 3 ) ? argv[3] : NULL;
+    const char* pFieldList = (argc > 3 ) ? (const char*)argv[3] : NULL;
     
     // Copy Fields.
     object->copyFields( pSimObject, pFieldList );

+ 9 - 9
Engine/source/console/persistenceManager.cpp

@@ -2204,7 +2204,7 @@ ConsoleMethod( PersistenceManager, setDirty, void, 3, 4, "(SimObject object, [fi
    {
       if (!Sim::findObject(argv[2], dirtyObject))
       {
-         Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
          return;
       }
    }
@@ -2213,7 +2213,7 @@ ConsoleMethod( PersistenceManager, setDirty, void, 3, 4, "(SimObject object, [fi
    
    if( dirtyObject == Sim::getRootGroup() )
    {
-      Con::errorf( "%s(): Cannot save RootGroup", argv[ 0 ] );
+      Con::errorf( "%s(): Cannot save RootGroup", (const char*)argv[ 0 ] );
       return;
    }
 
@@ -2234,7 +2234,7 @@ ConsoleMethod( PersistenceManager, removeDirty, void, 3, 3, "(SimObject object)"
    {
       if (!Sim::findObject(argv[2], dirtyObject))
       {
-         Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
          return;
       }
    }
@@ -2251,7 +2251,7 @@ ConsoleMethod( PersistenceManager, isDirty, bool, 3, 3, "(SimObject object)"
    {
       if (!Sim::findObject(argv[2], dirtyObject))
       {
-         Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
          return false;
       }
    }
@@ -2280,7 +2280,7 @@ ConsoleMethod( PersistenceManager, getDirtyObject, S32, 3, 3, "( index )"
    const S32 index = dAtoi( argv[2] );
    if ( index < 0 || index >= object->getDirtyList().size() )
    {
-      Con::warnf( "PersistenceManager::getDirtyObject() - Index (%s) out of range.", argv[2] );
+      Con::warnf( "PersistenceManager::getDirtyObject() - Index (%s) out of range.", (const char*)argv[2] );
       return 0;
    }
 
@@ -2333,7 +2333,7 @@ ConsoleMethod( PersistenceManager, saveDirtyObject, bool, 3, 3, "(SimObject obje
    {
       if (!Sim::findObject(argv[2], dirtyObject))
       {
-         Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
          return false;
       }
    }
@@ -2358,7 +2358,7 @@ ConsoleMethod( PersistenceManager, removeObjectFromFile, void, 3, 4, "(SimObject
    {
       if (!Sim::findObject(argv[2], dirtyObject))
       {
-         Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
          return;
       }
    }
@@ -2380,7 +2380,7 @@ ConsoleMethod( PersistenceManager, removeField, void, 4, 4, "(SimObject object,
    {
       if (!Sim::findObject(argv[2], dirtyObject))
       {
-         Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
          return;
       }
    }
@@ -2390,4 +2390,4 @@ ConsoleMethod( PersistenceManager, removeField, void, 4, 4, "(SimObject object,
       if (argv[3][0])
          object->addRemoveField(dirtyObject, argv[3]);
    }
-}
+}

+ 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((const char*)argv[1]);
    String spawnDataBlock;
    String spawnName;
    String spawnProperties;
    String spawnScript;
 
    if (argc >= 3)
-      spawnDataBlock = argv[2];
+      spawnDataBlock = (const char*)argv[2];
    if (argc >= 4)
-      spawnName = argv[3];
+      spawnName = (const char*)argv[3];
    if (argc >= 5)
-      spawnProperties = argv[4];
+      spawnProperties = (const char*)argv[4];
    if (argc >= 6)
-      spawnScript = argv[5];
+      spawnScript = (const char*)argv[5];
 
    SimObject* spawnObject = Sim::spawnObject(spawnClass, spawnDataBlock, spawnName, spawnProperties, spawnScript);
 

+ 9 - 0
Engine/source/console/sim.h

@@ -32,6 +32,9 @@
 #ifndef _MODULE_H_
 #include "core/module.h"
 #endif
+#ifndef _CONSOLE_H_
+#include "console/console.h"
+#endif
 
 // Forward Refs
 class SimSet;
@@ -122,9 +125,15 @@ namespace Sim
    SimDataBlockGroup *getDataBlockGroup();
    SimGroup* getRootGroup();
 
+   SimObject* findObject(ConsoleValueRef&);
    SimObject* findObject(SimObjectId);
    SimObject* findObject(const char* name);
    SimObject* findObject(const char* fileName, S32 declarationLine);
+   template<class T> inline bool findObject(ConsoleValueRef &ref,T*&t)
+   {
+      t = dynamic_cast<T*>(findObject(ref));
+      return t != NULL;
+   }
    template<class T> inline bool findObject(SimObjectId iD,T*&t)
    {
       t = dynamic_cast<T*>(findObject(iD));

+ 22 - 22
Engine/source/console/simEvents.cpp

@@ -28,30 +28,28 @@
 // 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 = new ConsoleValueRef[argc];
+   for (int i=0; i<argc; i++)
    {
-      mArgv[i] = argBase;
-      dStrcpy(mArgv[i], argv[i]);
-      argBase += dStrlen(argv[i]) + 1;
+      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 +58,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 +77,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 +122,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 +131,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);
 };

+ 5 - 0
Engine/source/console/simManager.cpp

@@ -328,6 +328,11 @@ SimObject* findObject(const char* fileName, S32 declarationLine)
    return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true);
 }
 
+SimObject* findObject(ConsoleValueRef &ref)
+{
+   return findObject((const char*)ref);
+}
+
 SimObject* findObject(const char* name)
 {
    PROFILE_SCOPE(SimFindObject);

+ 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 )

+ 2 - 2
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 )
    {
@@ -54,7 +54,7 @@ bool SimPersistSet::processArguments( S32 argc, const char** argv )
       Torque::UUID uuid;
       if( !uuid.fromString( argv[ i ] ) )
       {
-         Con::errorf( "SimPersistSet::processArguments - could not read UUID at index %i: %s", i, argv[ i ] );
+         Con::errorf( "SimPersistSet::processArguments - could not read UUID at index %i: %s", i, (const char*)argv[ i ] );
          continue;
       }
 

+ 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" );

+ 8 - 8
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;
 }
@@ -909,7 +909,7 @@ ConsoleMethod( SimSet, add, void, 3, 0,
       if(obj)
          object->addObject( obj );
       else
-         Con::printf("Set::add: Object \"%s\" doesn't exist", argv[ i ] );
+         Con::printf("Set::add: Object \"%s\" doesn't exist", (const char*)argv[ i ] );
    }
 }
 
@@ -934,7 +934,7 @@ ConsoleMethod( SimSet, remove, void, 3, 0,
       if(obj && object->find(object->begin(),object->end(),obj) != object->end())
          object->removeObject(obj);
       else
-         Con::printf("Set::remove: Object \"%s\" does not exist in set", argv[i]);
+         Con::printf("Set::remove: Object \"%s\" does not exist in set", (const char*)argv[i]);
       object->unlock();
    }
 }
@@ -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--;
+}

+ 46 - 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,43 @@ 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

@@ -494,9 +494,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 );
 }

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

@@ -1241,7 +1241,7 @@ ConsoleMethod( GuiMeshRoadEditorCtrl, setNodePosition, void, 3, 3, "" )
 	
 	if ( (count != 3) )
    {
-		Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
+		Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
       return;
    }
 
@@ -1268,7 +1268,7 @@ ConsoleMethod( GuiMeshRoadEditorCtrl, setNodeNormal, void, 3, 3, "" )
 	
 	if ( (count != 3) )
    {
-		Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
+		Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
       return;
    }
 
@@ -1306,4 +1306,4 @@ ConsoleMethod( GuiMeshRoadEditorCtrl, regenerate, void, 2, 2, "" )
 ConsoleMethod( GuiMeshRoadEditorCtrl, matchTerrainToRoad, void, 2, 2, "" )
 {
    object->matchTerrainToRoad();
-}
+}

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

@@ -1448,7 +1448,7 @@ ConsoleMethod( GuiRiverEditorCtrl, setNodePosition, void, 3, 3, "" )
 	
 	if ( (count != 3) )
    {
-		Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
+		Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
       return;
    }
 
@@ -1475,7 +1475,7 @@ ConsoleMethod( GuiRiverEditorCtrl, setNodeNormal, void, 3, 3, "" )
 	
 	if ( (count != 3) )
    {
-		Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
+		Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
       return;
    }
 
@@ -1508,4 +1508,4 @@ ConsoleMethod( GuiRiverEditorCtrl, regenerate, void, 2, 2, "" )
    River *river = object->getSelectedRiver();
    if ( river )
       river->regenerate();
-}
+}

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

@@ -1082,7 +1082,7 @@ ConsoleMethod( GuiRoadEditorCtrl, setNodePosition, void, 3, 3, "" )
 	
 	if ( (count != 3) )
    {
-		Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
+		Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
       return;
    }
 

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

@@ -409,7 +409,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

@@ -157,7 +157,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 );

+ 2 - 2
Engine/source/forest/forest.cpp

@@ -361,7 +361,7 @@ void Forest::saveDataFile( const char *path )
 
 ConsoleMethod( Forest, saveDataFile, bool, 2, 3, "saveDataFile( [path] )" )
 {   
-   object->saveDataFile( argc == 3 ? argv[2] : NULL );
+   object->saveDataFile( argc == 3 ? (const char*)argv[2] : NULL );
    return true;
 }
 
@@ -378,4 +378,4 @@ ConsoleMethod(Forest, regenCells, void, 2, 2, "()")
 ConsoleMethod(Forest, clear, void, 2, 2, "()" )
 {
    object->clear();
-}
+}

+ 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] );
 }

+ 3 - 3
Engine/source/gui/controls/guiPopUpCtrl.cpp

@@ -431,7 +431,7 @@ ConsoleMethod( GuiPopUpMenuCtrl, setEnumContent, void, 4, 4, "(string class, str
    // get it?
    if(!classRep)
    {
-      Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", argv[2]);
+      Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", (const char*)argv[2]);
       return;
    }
 
@@ -444,7 +444,7 @@ ConsoleMethod( GuiPopUpMenuCtrl, setEnumContent, void, 4, 4, "(string class, str
    // found it?   
    if(i == classRep->mFieldList.size())
    {   
-      Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", argv[3], argv[2]);
+      Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", (const char*)argv[3], (const char*)argv[2]);
       return;
    }
 
@@ -454,7 +454,7 @@ ConsoleMethod( GuiPopUpMenuCtrl, setEnumContent, void, 4, 4, "(string class, str
    // check the type
    if( !conType->getEnumTable() )
    {
-      Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", argv[3], argv[2]);
+      Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", (const char*)argv[3], (const char*)argv[2]);
       return;
    }
 

+ 3 - 3
Engine/source/gui/controls/guiPopUpCtrlEx.cpp

@@ -605,7 +605,7 @@ ConsoleMethod( GuiPopUpMenuCtrlEx, setEnumContent, void, 4, 4,
    // get it?
    if(!classRep)
    {
-      Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", argv[2]);
+      Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", (const char*)argv[2]);
       return;
    }
 
@@ -618,7 +618,7 @@ ConsoleMethod( GuiPopUpMenuCtrlEx, setEnumContent, void, 4, 4,
    // found it?   
    if(i == classRep->mFieldList.size())
    {   
-      Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", argv[3], argv[2]);
+      Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", (const char*)argv[3], (const char*)argv[2]);
       return;
    }
 
@@ -628,7 +628,7 @@ ConsoleMethod( GuiPopUpMenuCtrlEx, setEnumContent, void, 4, 4,
    // check the type
    if( !conType->getEnumTable() )
    {
-      Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", argv[3], argv[2]);
+      Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", (const char*)argv[3], (const char*)argv[2]);
       return;
    }
 

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

@@ -4929,7 +4929,7 @@ ConsoleMethod( GuiTreeViewCtrl, setItemTooltip, void, 4, 4, "( int id, string te
       return;
    }
    
-   item->mTooltip = argv[ 3 ];
+   item->mTooltip = (const char*)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." )

+ 3 - 3
Engine/source/gui/core/guiCanvas.cpp

@@ -2022,7 +2022,7 @@ ConsoleMethod( GuiCanvas, pushDialog, void, 3, 5, "(GuiControl ctrl, int layer=0
 
    if (!	Sim::findObject(argv[2], gui))
    {
-      Con::printf("%s(): Invalid control: %s", argv[0], argv[2]);
+      Con::printf("%s(): Invalid control: %s", (const char*)argv[0], (const char*)argv[2]);
       return;
    }
 
@@ -2067,7 +2067,7 @@ ConsoleMethod( GuiCanvas, popDialog, void, 2, 3, "(GuiControl ctrl=NULL)"
    {
       if (!Sim::findObject(argv[2], gui))
       {
-         Con::printf("%s(): Invalid control: %s", argv[0], argv[2]);
+         Con::printf("%s(): Invalid control: %s", (const char*)argv[0], (const char*)argv[2]);
          return;
       }
    }
@@ -2718,4 +2718,4 @@ ConsoleMethod( GuiCanvas, hideWindow, void, 2, 2, "" )
    object->getPlatformWindow()->hide();
    WindowManager->setDisplayWindow(false);
    object->getPlatformWindow()->setDisplayWindow(false);
-}
+}

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

@@ -307,7 +307,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

@@ -327,7 +327,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();

+ 5 - 5
Engine/source/gui/editor/guiEditCtrl.cpp

@@ -2540,7 +2540,7 @@ ConsoleMethod( GuiEditCtrl, setCurrentAddSet, void, 3, 3, "(GuiControl ctrl)")
 
    if (!Sim::findObject(argv[2], addSet))
    {
-      Con::printf("%s(): Invalid control: %s", argv[0], argv[2]);
+      Con::printf("%s(): Invalid control: %s", (const char*)argv[0], (const char*)argv[2]);
       return;
    }
    object->setCurrentAddSet(addSet);
@@ -2700,7 +2700,7 @@ ConsoleMethod( GuiEditCtrl, readGuides, void, 3, 4, "( GuiControl ctrl [, int ax
    GuiControl* ctrl;
    if( !Sim::findObject( argv[ 2 ], ctrl ) )
    {
-      Con::errorf( "GuiEditCtrl::readGuides - no control '%s'", argv[ 2 ] );
+      Con::errorf( "GuiEditCtrl::readGuides - no control '%s'", (const char*)argv[ 2 ] );
       return;
    }
    
@@ -2711,7 +2711,7 @@ ConsoleMethod( GuiEditCtrl, readGuides, void, 3, 4, "( GuiControl ctrl [, int ax
       S32 axis = dAtoi( argv[ 3 ] );
       if( axis < 0 || axis > 1 )
       {
-         Con::errorf( "GuiEditCtrl::readGuides - invalid axis '%s'", argv[ 3 ] );
+         Con::errorf( "GuiEditCtrl::readGuides - invalid axis '%s'", (const char*)argv[ 3 ] );
          return;
       }
       
@@ -2733,7 +2733,7 @@ ConsoleMethod( GuiEditCtrl, writeGuides, void, 3, 4, "( GuiControl ctrl [, int a
    GuiControl* ctrl;
    if( !Sim::findObject( argv[ 2 ], ctrl ) )
    {
-      Con::errorf( "GuiEditCtrl::writeGuides - no control '%i'", argv[ 2 ] );
+      Con::errorf( "GuiEditCtrl::writeGuides - no control '%i'", (const char*)argv[ 2 ] );
       return;
    }
    
@@ -2744,7 +2744,7 @@ ConsoleMethod( GuiEditCtrl, writeGuides, void, 3, 4, "( GuiControl ctrl [, int a
       S32 axis = dAtoi( argv[ 3 ] );
       if( axis < 0 || axis > 1 )
       {
-         Con::errorf( "GuiEditCtrl::writeGuides - invalid axis '%s'", argv[ 3 ] );
+         Con::errorf( "GuiEditCtrl::writeGuides - invalid axis '%s'", (const char*)argv[ 3 ] );
          return;
       }
       

+ 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);
 }
 

+ 3 - 3
Engine/source/gui/editor/guiInspector.cpp

@@ -777,7 +777,7 @@ ConsoleMethod( GuiInspector, inspect, void, 3, 3, "Inspect(Object)")
    if(!target)
    {
       if(dAtoi(argv[2]) > 0)
-         Con::warnf("%s::inspect(): invalid object: %s", argv[0], argv[2]);
+         Con::warnf("%s::inspect(): invalid object: %s", (const char*)argv[0], (const char*)argv[2]);
 
       object->clearInspectObjects();
       return;
@@ -793,7 +793,7 @@ ConsoleMethod( GuiInspector, addInspect, void, 3, 4, "( id object, (bool autoSyn
    SimObject* obj;
    if( !Sim::findObject( argv[ 2 ], obj ) )
    {
-      Con::errorf( "%s::addInspect(): invalid object: %s", argv[ 0 ], argv[ 2 ] );
+      Con::errorf( "%s::addInspect(): invalid object: %s", (const char*)argv[ 0 ], (const char*)argv[ 2 ] );
       return;
    }
 
@@ -810,7 +810,7 @@ ConsoleMethod( GuiInspector, removeInspect, void, 3, 3, "( id object ) - Remove
    SimObject* obj;
    if( !Sim::findObject( argv[ 2 ], obj ) )
    {
-      Con::errorf( "%s::removeInspect(): invalid object: %s", argv[ 0 ], argv[ 2 ] );
+      Con::errorf( "%s::removeInspect(): invalid object: %s", (const char*)argv[ 0 ], (const char*)argv[ 2 ] );
       return;
    }
    

+ 1 - 1
Engine/source/gui/editor/guiInspectorTypes.cpp

@@ -571,7 +571,7 @@ void GuiInspectorTypeFileName::updateValue()
 
 ConsoleMethod( GuiInspectorTypeFileName, apply, void, 3,3, "apply(newValue);" )
 {
-   String path( argv[2] );
+   String path( (const char*)argv[2] );
    if ( path.isNotEmpty() )
       path = Platform::makeRelativePathName( path, Platform::getMainDotCsDir() );
       

+ 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.")

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

@@ -212,7 +212,7 @@ ConsoleStaticMethod( EditorIconRegistry, findIconBySimObject, const char*, 2, 2,
    SimObject *obj = NULL;
    if ( !Sim::findObject( argv[1], obj ) )
    {
-      Con::warnf( "EditorIconRegistry::findIcon, parameter %d was not a SimObject!", argv[1] );
+      Con::warnf( "EditorIconRegistry::findIcon, parameter %d was not a SimObject!", (const char*)argv[1] );
       return NULL;
    }
 

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

@@ -792,7 +792,7 @@ ConsoleMethod( GuiDecalEditorCtrl, deleteSelectedDecal, void, 2, 2, "deleteSelec
 
 ConsoleMethod( GuiDecalEditorCtrl, deleteDecalDatablock, void, 3, 3, "deleteSelectedDecalDatablock( String datablock )" )
 {
-	String lookupName( argv[2] );
+	String lookupName( (const char*)argv[2] );
 	if( lookupName == String::EmptyString )
 		return;
 	
@@ -801,7 +801,7 @@ ConsoleMethod( GuiDecalEditorCtrl, deleteDecalDatablock, void, 3, 3, "deleteSele
 
 ConsoleMethod( GuiDecalEditorCtrl, setMode, void, 3, 3, "setMode( String mode )()" )
 {
-	String newMode = ( argv[2] );
+	String newMode = ( (const char*)argv[2] );
 	object->setMode( newMode );
 }
 
@@ -869,7 +869,7 @@ ConsoleMethod( GuiDecalEditorCtrl, editDecalDetails, void, 4, 4, "editDecalDetai
 	
 	if ( (count != 7) )
    {
-		Con::printf("Failed to parse decal information \"px py pz tx ty tz s\" from '%s'", argv[3]);
+		Con::printf("Failed to parse decal information \"px py pz tx ty tz s\" from '%s'", (const char*)argv[3]);
       return;
    }
 
@@ -1254,4 +1254,4 @@ void DBRetargetUndoAction::redo()
 	if ( mEditor->isMethod( "rebuildInstanceTree" ) )
 		Con::executef( mEditor, "rebuildInstanceTree" );
 }
-#endif
+#endif

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

@@ -2434,7 +2434,7 @@ ConsoleMethod( TerrainEditor, attachTerrain, void, 2, 3, "(TerrainBlock terrain)
          terrains.push_back(terrBlock);
 
       if(terrains.size() == 0)
-         Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::attach: failed to attach to object '%s'", argv[2]);
+         Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::attach: failed to attach to object '%s'", (const char*)argv[2]);
    }
 
    if (terrains.size() > 0)

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

@@ -2760,7 +2760,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++)
    {
@@ -3210,7 +3210,7 @@ ConsoleMethod( WorldEditor, setActiveSelection, void, 3, 3, "( id set ) - Set th
    WorldEditorSelection* selection;
    if( !Sim::findObject( argv[ 2 ], selection ) )
    {
-      Con::errorf( "WorldEditor::setActiveSelectionSet - no selection set '%s'", argv[ 2 ] );
+      Con::errorf( "WorldEditor::setActiveSelectionSet - no selection set '%s'", (const char*)argv[ 2 ] );
       return;
    }
    
@@ -3337,14 +3337,14 @@ ConsoleMethod( WorldEditor, alignByBounds, void, 3, 3, "(int boundsAxis)"
               "Align all selected objects against the given bounds axis.")
 {
 	if(!object->alignByBounds(dAtoi(argv[2])))
-		Con::warnf(ConsoleLogEntry::General, avar("worldEditor.alignByBounds: invalid bounds axis '%s'", argv[2]));
+		Con::warnf(ConsoleLogEntry::General, avar("worldEditor.alignByBounds: invalid bounds axis '%s'", (const char*)argv[2]));
 }
 
 ConsoleMethod( WorldEditor, alignByAxis, void, 3, 3, "(int axis)"
               "Align all selected objects along the given axis.")
 {
 	if(!object->alignByAxis(dAtoi(argv[2])))
-		Con::warnf(ConsoleLogEntry::General, avar("worldEditor.alignByAxis: invalid axis '%s'", argv[2]));
+		Con::warnf(ConsoleLogEntry::General, avar("worldEditor.alignByAxis: invalid axis '%s'", (const char*)argv[2]));
 }
 
 ConsoleMethod( WorldEditor, resetSelectedRotation, void, 2, 2, "")
@@ -3549,7 +3549,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/gui/worldEditor/worldEditorSelection.cpp

@@ -684,7 +684,7 @@ ConsoleMethod( WorldEditorSelection, union, void, 3, 3, "( SimSet set ) - Add al
    SimSet* selection;
    if( !Sim::findObject( argv[ 2 ], selection ) )
    {
-      Con::errorf( "WorldEditorSelection::union - no SimSet '%s'", argv[ 2 ] );
+      Con::errorf( "WorldEditorSelection::union - no SimSet '%s'", (const char*)argv[ 2 ] );
       return;
    }
    
@@ -700,7 +700,7 @@ ConsoleMethod( WorldEditorSelection, subtract, void, 3, 3, "( SimSet ) - Remove
    SimSet* selection;
    if( !Sim::findObject( argv[ 2 ], selection ) )
    {
-      Con::errorf( "WorldEditorSelection::subtract - no SimSet '%s'", argv[ 2 ] );
+      Con::errorf( "WorldEditorSelection::subtract - no SimSet '%s'", (const char*)argv[ 2 ] );
       return;
    }
    

+ 1 - 1
Engine/source/i18n/i18n.cpp

@@ -78,7 +78,7 @@ ConsoleFunction(setCoreLangTable, void, 2, 2, "(string LangTable)"
    if(Sim::findObject(argv[1], lt))
 		gCoreLangTable = lt;
    else
-      Con::errorf("setCoreLangTable - Unable to find LanTable '%s'", argv[1]);
+      Con::errorf("setCoreLangTable - Unable to find LanTable '%s'", (const char*)argv[1]);
 }
 
 //-----------------------------------------------------------------------------

+ 3 - 3
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(argv[1], argv[2]);
 }
 
 ConsoleFunction( getMaterialMapping, const char*, 2, 2, "(string texName)\n"
@@ -487,5 +487,5 @@ ConsoleFunction( dumpMaterialInstances, void, 1, 1,
 ConsoleFunction( getMapEntry, const char *, 2, 2, 
    "@hide")
 {
-	return MATMGR->getMapEntry( String(argv[1]) );
-}
+	return MATMGR->getMapEntry( argv[1] );
+}

+ 2 - 2
Engine/source/platformMac/macCarbFileio.mm

@@ -889,7 +889,7 @@ bool Platform::fileTimeToString(FileTime * time, char * string, U32 strLen) { re
 //-----------------------------------------------------------------------------
 #if defined(TORQUE_DEBUG)
 ConsoleFunction(testHasSubdir,void,2,2,"tests platform::hasSubDirectory") {
-   Con::printf("testing %s",argv[1]);
+   Con::printf("testing %s",(const char*)argv[1]);
    Platform::addExcludedDirectory(".svn");
    if(Platform::hasSubDirectory(argv[1]))
       Con::printf(" has subdir");
@@ -906,7 +906,7 @@ ConsoleFunction(testDumpDirectories,void,4,4,"testDumpDirectories('path', int de
    
    Platform::dumpDirectories(argv[1], paths, depth, noBasePath);
    
-   Con::printf("Dumping directories starting from %s with depth %i", argv[1],depth);
+   Con::printf("Dumping directories starting from %s with depth %i", (const char*)argv[1],depth);
    
    for(Vector<StringTableEntry>::iterator itr = paths.begin(); itr != paths.end(); itr++) {
       Con::printf(*itr);

+ 1 - 1
Engine/source/platformWin32/winInput.cpp

@@ -508,7 +508,7 @@ void Input::log( const char* format, ... )
 ConsoleFunction( inputLog, void, 2, 2, "inputLog( string )" )
 {
    argc;
-   Input::log( "%s\n", argv[1] );
+   Input::log( "%s\n", (const char*)argv[1] );
 }
 #endif // LOG_INPUT
 

+ 1 - 1
Engine/source/platformX86UNIX/x86UNIXInput.client.cpp

@@ -335,7 +335,7 @@ void Input::log( const char* format, ... )
 ConsoleFunction( inputLog, void, 2, 2, "inputLog( string )" )
 {
    argc;
-   Input::log( "%s\n", argv[1] );
+   Input::log( "%s\n", (const char*)argv[1] );
 }
 #endif // LOG_INPUT
 

+ 1 - 1
Engine/source/platformX86UNIX/x86UNIXMath.cpp

@@ -70,7 +70,7 @@ ConsoleFunction( MathInit, void, 1, 10, "(detect|C|FPU|MMX|3DNOW|SSE|...)")
          properties |= CPU_PROP_SSE;
          continue;
       }
-      Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", *argv);
+      Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", (const char*)argv[0]);
    }
    Math::init(properties);
 }

+ 3 - 3
Engine/source/postFx/postEffectVis.cpp

@@ -400,7 +400,7 @@ ConsoleStaticMethod( PfxVis, open, void, 2, 3, "( PostEffect, [bool clear = fals
    PostEffect *pfx;
    if ( !Sim::findObject( argv[1], pfx ) )
    {
-      Con::errorf( "PfxVis::add, argument %s was not a PostEffect", argv[1] );
+      Con::errorf( "PfxVis::add, argument %s was not a PostEffect", (const char*)argv[1] );
       return;
    }
 
@@ -450,9 +450,9 @@ ConsoleStaticMethod( PfxVis, onWindowClosed, void, 2, 2, "( GuiWindowCtrl )"
    GuiWindowCtrl *ctrl;
    if ( !Sim::findObject( argv[1], ctrl ) )
    {
-      Con::errorf( "PfxVis::onWindowClosed, argument %s was not a GuiWindowCtrl", argv[1] );
+      Con::errorf( "PfxVis::onWindowClosed, argument %s was not a GuiWindowCtrl", (const char*)argv[1] );
       return;
    }
 
    PFXVIS->onWindowClosed( ctrl );
-}
+}

+ 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 );

+ 3 - 3
Engine/source/sfx/sfxSystem.cpp

@@ -1455,7 +1455,7 @@ ConsoleFunction( sfxCreateSource, S32, 2, 6,
       description = dynamic_cast< SFXDescription* >( Sim::findObject( argv[1] ) );
       if ( !description )
       {
-         Con::printf( "Unable to locate sound track/description '%s'", argv[1] );
+         Con::printf( "Unable to locate sound track/description '%s'", (const char*)argv[1] );
          return 0;
       }
    }
@@ -1561,7 +1561,7 @@ ConsoleFunction( sfxPlay, S32, 2, 5, "( SFXSource source | ( SFXTrack track [, f
    SFXTrack* track = dynamic_cast<SFXTrack*>( Sim::findObject( argv[1] ) );
    if ( !track )
    {
-      Con::printf( "Unable to locate sfx track '%s'", argv[1] );
+      Con::printf( "Unable to locate sfx track '%s'", (const char*)argv[1] );
       return 0;
    }
 
@@ -1664,7 +1664,7 @@ ConsoleFunction( sfxPlayOnce, S32, 2, 6,
       description = dynamic_cast< SFXDescription* >( Sim::findObject( argv[1] ) );
       if( !description )
       {
-         Con::errorf( "sfxPlayOnce - Unable to locate sound track/description '%s'", argv[1] );
+         Con::errorf( "sfxPlayOnce - Unable to locate sound track/description '%s'", (const char*)argv[1] );
          return 0;
       }
    }

+ 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:
          

+ 10 - 8
Engine/source/sim/actionMap.cpp

@@ -1872,7 +1872,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(
@@ -1920,14 +1921,15 @@ static ConsoleDocFragment _ActionMapbindObj2(
 ConsoleMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier spec, mod...], command, object)"
 			  "@hide")
 {
-    SimObject* simObject = Sim::findObject(argv[argc - 1]);
-    if ( simObject == NULL )
-    {
-        Con::warnf("ActionMap::bindObj() - Cannot bind, specified object was not found!");
-        return false;
-    }
+   SimObject* simObject = Sim::findObject(argv[argc - 1]);
+   if ( simObject == NULL )
+   {
+      Con::warnf("ActionMap::bindObj() - Cannot bind, specified object was not found!");
+      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();
+
+   // Ensure NetAddress is cleared
+   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 = (const char*)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 = (const char*)argv[3];
 
    Con::expandScriptFilename( filePrefix, sizeof( filePrefix ), argv[2] );
 

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

@@ -139,13 +139,13 @@ ConsoleFunction( enumColladaForImport, bool, 3, 3,
    GuiTreeViewCtrl* tree;
    if (!Sim::findObject(argv[2], tree))
    {
-      Con::errorf("enumColladaScene::Could not find GuiTreeViewCtrl '%s'", argv[2]);
+      Con::errorf("enumColladaScene::Could not find GuiTreeViewCtrl '%s'", (const char*)argv[2]);
       return false;
    }
 
    // 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;
 

+ 2 - 2
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.
@@ -172,7 +172,7 @@ ConsoleFunction( loadColladaLights, bool, 2, 4,
       if (!Sim::findObject(argv[2], group)) {
          // Create the group if it could not be found
          group = new SimGroup;
-         if (group->registerObject(argv[2])) {
+         if (group->registerObject((const char*)argv[2])) {
             if (missionGroup)
                missionGroup->addObject(group);
          }

+ 1 - 1
Engine/source/util/messaging/eventManager.cpp

@@ -471,7 +471,7 @@ ConsoleMethod( EventManager, subscribe, bool, 4, 5, "( SimObject listener, Strin
       return false;
    }
 
-   return object->subscribe( cbObj, argv[3], argc > 4 ? argv[4] : NULL );
+   return object->subscribe( cbObj, argv[3], argc > 4 ? (const char*)argv[4] : NULL );
 }
 
 ConsoleMethod( EventManager, remove, void, 4, 4, "( SimObject listener, String event )\n\n"

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

@@ -486,9 +486,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 "";
 }
@@ -689,8 +689,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]) );
 	}
 }
 

+ 2 - 2
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 = (const char*)argv[ 2 ];
       
    CompoundUndoAction* action = object->pushCompound( name );
    if( !action )
@@ -584,7 +584,7 @@ ConsoleMethod( UndoManager, popCompound, void, 2, 3, "( bool discard=false ) - P
 {
    if( !object->getCompoundStackDepth() )
    {
-      Con::errorf( "%s::popCompound - no compound on stack", argv[ 0 ] );
+      Con::errorf( "%s::popCompound - no compound on stack", (const char*)argv[ 0 ] );
       return;
    }