Browse Source

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

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

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

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

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

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

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

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

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

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

@@ -79,7 +79,7 @@ public:
    void disconnect();
    void disconnect();
    State getState() { return mState; }
    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 send(const U8 *buffer, U32 bufferLen);
    void addToTable(NetSocket newTag);
    void addToTable(NetSocket newTag);
    void removeFromTable();
    void removeFromTable();

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

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

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

@@ -262,7 +262,8 @@ extern "C" {
 		if (!entry)
 		if (!entry)
 			return;
 			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)
 	F32 torque_callfloatfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
@@ -273,7 +274,8 @@ extern "C" {
 		if (!entry)
 		if (!entry)
 			return 0.0f;
 			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)
 	S32 torque_callintfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
@@ -284,7 +286,8 @@ extern "C" {
 		if (!entry)
 		if (!entry)
 			return 0;
 			return 0;
 
 
-		return entry->cb.mIntCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mIntCallbackFunc(NULL, args.count(), args);
 	}
 	}
 
 
 
 
@@ -295,7 +298,8 @@ extern "C" {
 		if (!entry)
 		if (!entry)
 			return "";
 			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)
 	bool torque_callboolfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
@@ -305,7 +309,8 @@ extern "C" {
 		if (!entry)
 		if (!entry)
 			return "";
 			return "";
 
 
-		return entry->cb.mBoolCallbackFunc(NULL, argc, argv);      
+		StringStackConsoleWrapper args(argc, argv);
+		return entry->cb.mBoolCallbackFunc(NULL, args.count(), args);
 	}
 	}
 
 
 
 
@@ -319,7 +324,8 @@ extern "C" {
 		if(!entry->mFunctionOffset)
 		if(!entry->mFunctionOffset)
 			return "";
 			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))
 		if (!ret || !dStrlen(ret))
 			return "";
 			return "";

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

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

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

@@ -62,7 +62,7 @@ protected:
    /// Internal callMethod : Actually does component notification and script method execution
    /// 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
    ///  @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
    ///   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:
 public:
 
 
@@ -75,7 +75,7 @@ public:
 #endif
 #endif
 
 
    /// Call Method
    /// 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
    /// Call Method format string
    const char* callMethod( S32 argc, const char* methodName, ... );
    const char* callMethod( S32 argc, const char* methodName, ... );

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

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

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

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

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

@@ -27,7 +27,7 @@ class ICallMethod
 {
 {
 public:
 public:
    virtual const char* callMethod( S32 argc, const char* methodName, ... ) = 0;
    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
 #endif

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

@@ -158,7 +158,7 @@ SimXMLDocument::~SimXMLDocument()
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------
 // Included for completeness.
 // Included for completeness.
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------
-bool SimXMLDocument::processArguments(S32 argc, const char** argv)
+bool SimXMLDocument::processArguments(S32 argc, ConsoleValueRef *argv)
 {
 {
    return argc == 0;
    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
       // tie in to the script language.  The .cc file has more in depth
       // comments on these.
       // comments on these.
       //-----------------------------------------------------------------------
       //-----------------------------------------------------------------------
-      bool processArguments(S32 argc, const char** argv);
+      bool processArguments(S32 argc, ConsoleValueRef *argv);
       bool onAdd();
       bool onAdd();
       void onRemove();
       void onRemove();
       static void initPersistFields();
       static void initPersistFields();

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

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

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

@@ -27,6 +27,8 @@
 #include "console/consoleParser.h"
 #include "console/consoleParser.h"
 
 
 class Stream;
 class Stream;
+class ConsoleValue;
+class ConsoleValueRef;
 
 
 /// Core TorqueScript code management class.
 /// Core TorqueScript code management class.
 ///
 ///
@@ -146,8 +148,8 @@ public:
    /// -1 a new frame is created. If the index is out of range the
    /// -1 a new frame is created. If the index is out of range the
    /// top stack frame is used.
    /// top stack frame is used.
    /// @param packageName The code package name or null.
    /// @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);
       S32 setFrame = -1);
 };
 };
 
 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -540,7 +540,7 @@ class SimObject: public ConsoleObject
       
       
       virtual ~SimObject();
       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];
    static char idB[64];
    dSprintf( idB, sizeof( idB ), "%d", objB->getId() );
    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 )
 void SimObjectList::scriptSort( const String &scriptCallback )

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

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

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

@@ -58,7 +58,7 @@ class SimPersistSet : public SimSet
       // SimSet.
       // SimSet.
       virtual void addObject( SimObject* );
       virtual void addObject( SimObject* );
       virtual void write( Stream &stream, U32 tabStop, U32 flags = 0 );
       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_CONOBJECT( SimPersistSet );
       DECLARE_CATEGORY( "Console" );
       DECLARE_CATEGORY( "Console" );

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

@@ -228,11 +228,11 @@ void SimSet::scriptSort( const String &scriptCallbackFn )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-void SimSet::callOnChildren( const String &method, S32 argc, const char *argv[], bool executeOnChildGroups )
+void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups )
 {
 {
    // Prep the arguments for the console exec...
    // Prep the arguments for the console exec...
    // Make sure and leave args[1] empty.
    // Make sure and leave args[1] empty.
-   const char* args[21];
+   ConsoleValueRef args[21];
    args[0] = method.c_str();
    args[0] = method.c_str();
    for (S32 i = 0; i < argc; i++)
    for (S32 i = 0; i < argc; i++)
       args[i + 2] = argv[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;
    return true;
 }
 }
@@ -973,7 +973,7 @@ ConsoleMethod( SimSet, callOnChildren, void, 3, 0,
    "@note This method recurses into all SimSets that are children to the set.\n\n"
    "@note This method recurses into all SimSets that are children to the set.\n\n"
    "@see callOnChildrenNoRecurse" )
    "@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"
    "@note This method does not recurse into child SimSets.\n\n"
    "@see callOnChildren" )
    "@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"
 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." )
    "@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
       /// Return the number of objects in this set as well as all sets that are contained
       /// in this set and its children.
       /// in this set and its children.
@@ -434,7 +434,7 @@ class SimGroup: public SimSet
       virtual SimObject* findObject(const char* name);
       virtual SimObject* findObject(const char* name);
       virtual void onRemove();
       virtual void onRemove();
 
 
-      virtual bool processArguments( S32 argc, const char** argv );
+      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
 
 
       DECLARE_CONOBJECT( SimGroup );
       DECLARE_CONOBJECT( SimGroup );
 };
 };

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

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

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

@@ -36,6 +36,8 @@
 #endif
 #endif
 
 
 
 
+
+
 /// Core stack for interpreter operations.
 /// Core stack for interpreter operations.
 ///
 ///
 /// This class provides some powerful semantics for working with strings, and is
 /// This class provides some powerful semantics for working with strings, and is
@@ -185,6 +187,11 @@ struct StringStack
       return mBuffer + mStart;
       return mBuffer + mStart;
    }
    }
 
 
+   inline const char *getPreviousStringValue()
+   {
+      return mBuffer + mStartOffsets[mStartStackSize-1];
+   }
+
    /// Advance the start stack, placing a zero length string on the top.
    /// Advance the start stack, placing a zero length string on the top.
    ///
    ///
    /// @note You should use StringStack::push, not this, if you want to
    /// @note You should use StringStack::push, not this, if you want to
@@ -275,4 +282,42 @@ struct StringStack
    void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
    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
 #endif

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

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

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

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

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

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

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

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

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

@@ -406,7 +406,7 @@ void WaterObject::inspectPostApply()
    setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask );
    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 ) )
    if( typeid( *this ) == typeid( WaterObject ) )
    {
    {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -264,7 +264,7 @@ ConsoleMethod( CreatorTree, fileNameMatch, bool, 5, 5, "(string world, string ty
    if(dToupper(argv[4][0]) != dToupper(argv[2][0]))
    if(dToupper(argv[4][0]) != dToupper(argv[2][0]))
       return(false);
       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.")
 ConsoleMethod( CreatorTree, getSelected, S32, 2, 2, "Return a handle to the currently selected item.")

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -316,7 +316,7 @@ void SFXSource::initPersistFields()
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-bool SFXSource::processArguments( S32 argc, const char **argv )
+bool SFXSource::processArguments( S32 argc, ConsoleValueRef *argv )
 {
 {
    // Don't allow subclasses of this to be created via script.  Force
    // Don't allow subclasses of this to be created via script.  Force
    // usage of the SFXSystem functions.
    // 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 
       /// We overload this to disable creation of 
       /// a source via script 'new'.
       /// a source via script 'new'.
-      virtual bool processArguments( S32 argc, const char **argv );
+      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
       
       
       // Console getters/setters.
       // Console getters/setters.
       static bool _setDescription( void *obj, const char *index, const char *data );
       static bool _setDescription( void *obj, const char *index, const char *data );

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

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

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

@@ -57,7 +57,7 @@ class SFXTrack : public SimDataBlock
       StringTableEntry mParameters[ MaxNumParameters ];
       StringTableEntry mParameters[ MaxNumParameters ];
    
    
       /// Overload this to disable direct instantiation of this class via script 'new'.
       /// 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:
    public:
          
          

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

@@ -1746,7 +1746,8 @@ static ConsoleDocFragment _ActionMapbind2(
 ConsoleMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier spec, mod...], command )" 
 ConsoleMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier spec, mod...], command )" 
 			  "@hide")
 			  "@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(
 static ConsoleDocFragment _ActionMapbindObj1(
@@ -1801,7 +1802,9 @@ ConsoleMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier spec
         return false;
         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
    // Disable starting a new journal recording or playback from here on
    Journal::Disable();
    Journal::Disable();
+
+   // jamesu - netAddress is not set
+   dMemset(&mNetAddress, '\0', sizeof(NetAddress));
 }
 }
 
 
 NetConnection::~NetConnection()
 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];
    UTF8 fileName[1024];
    String format = "png";
    String format = "png";
    if( argc > 3 )
    if( argc > 3 )
-      format = argv[ 3 ];
+      format = (String)argv[ 3 ];
 
 
    Con::expandScriptFilename( fileName, sizeof( fileName ), argv[2] );
    Con::expandScriptFilename( fileName, sizeof( fileName ), argv[2] );
 
 
@@ -153,7 +153,7 @@ ConsoleMethod( TerrainBlock, exportLayerMaps, bool, 3, 4, "(string filePrefix, [
    UTF8 filePrefix[1024];
    UTF8 filePrefix[1024];
    String format = "png";
    String format = "png";
    if( argc > 3 )
    if( argc > 3 )
-      format = argv[3];
+      format = (String)argv[3];
 
 
    Con::expandScriptFilename( filePrefix, sizeof( filePrefix ), argv[2] );
    Con::expandScriptFilename( filePrefix, sizeof( filePrefix ), argv[2] );
 
 

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

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

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

@@ -162,7 +162,7 @@ ConsoleFunction( loadColladaLights, bool, 2, 4,
    "@ingroup Editors\n"
    "@ingroup Editors\n"
    "@internal")
    "@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
    // Optional group to add the lights to. Create if it does not exist, and use
    // the MissionGroup if not specified.
    // the MissionGroup if not specified.

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

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

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

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