mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
initial port of the new interpreter
This commit is contained in:
parent
5d2654b1ba
commit
35500a87c6
47 changed files with 3675 additions and 5839 deletions
|
|
@ -331,7 +331,7 @@ DefineEngineStringlyVariadicMethod(GameConnection, setConnectArgs, void, 3, 17,
|
||||||
|
|
||||||
"@see GameConnection::onConnect()\n\n")
|
"@see GameConnection::onConnect()\n\n")
|
||||||
{
|
{
|
||||||
StringStackWrapper args(argc - 2, argv + 2);
|
ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
|
||||||
object->setConnectArgs(args.count(), args);
|
object->setConnectArgs(args.count(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -494,11 +494,17 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
|
||||||
*errorString = "CR_INVALID_ARGS";
|
*errorString = "CR_INVALID_ARGS";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ConsoleValueRef connectArgv[MaxConnectArgs + 3];
|
ConsoleValue connectArgv[MaxConnectArgs + 3];
|
||||||
ConsoleValue connectArgvValue[MaxConnectArgs + 3];
|
ConsoleValue connectArgvValue[MaxConnectArgs + 3];
|
||||||
|
|
||||||
|
// TODO(JTH): Fix pls.
|
||||||
|
AssertISV(false, "TODO: FIX CONSOLE VALUE");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
for(U32 i = 0; i < mConnectArgc+3; i++)
|
for(U32 i = 0; i < mConnectArgc+3; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
connectArgv[i].value = &connectArgvValue[i];
|
connectArgv[i].value = &connectArgvValue[i];
|
||||||
connectArgvValue[i].init();
|
connectArgvValue[i].init();
|
||||||
}
|
}
|
||||||
|
|
@ -524,6 +530,7 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
@ -1088,7 +1095,7 @@ bool GameConnection::readDemoStartBlock(BitStream *stream)
|
||||||
void GameConnection::demoPlaybackComplete()
|
void GameConnection::demoPlaybackComplete()
|
||||||
{
|
{
|
||||||
static const char* demoPlaybackArgv[1] = { "demoPlaybackComplete" };
|
static const char* demoPlaybackArgv[1] = { "demoPlaybackComplete" };
|
||||||
static StringStackConsoleWrapper demoPlaybackCmd(1, demoPlaybackArgv);
|
static StringArrayToConsoleValueWrapper demoPlaybackCmd(1, demoPlaybackArgv);
|
||||||
|
|
||||||
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(demoPlaybackCmd.argc, demoPlaybackCmd.argv, false));
|
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(demoPlaybackCmd.argc, demoPlaybackCmd.argv, false));
|
||||||
Parent::demoPlaybackComplete();
|
Parent::demoPlaybackComplete();
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ DefineEngineStringlyVariadicFunction( commandToServer, void, 2, RemoteCommandEve
|
||||||
NetConnection *conn = NetConnection::getConnectionToServer();
|
NetConnection *conn = NetConnection::getConnectionToServer();
|
||||||
if(!conn)
|
if(!conn)
|
||||||
return;
|
return;
|
||||||
StringStackWrapper args(argc - 1, argv + 1);
|
ConsoleValueToStringArrayWrapper args(argc - 1, argv + 1);
|
||||||
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
|
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,7 +289,7 @@ DefineEngineStringlyVariadicFunction( commandToClient, void, 3, RemoteCommandEve
|
||||||
NetConnection *conn;
|
NetConnection *conn;
|
||||||
if(!Sim::findObject(argv[1], conn))
|
if(!Sim::findObject(argv[1], conn))
|
||||||
return;
|
return;
|
||||||
StringStackWrapper args(argc - 2, argv + 2);
|
ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
|
||||||
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
|
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,13 +236,13 @@ TCPObject::~TCPObject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCPObject::processArguments(S32 argc, ConsoleValueRef *argv)
|
bool TCPObject::processArguments(S32 argc, ConsoleValue *argv)
|
||||||
{
|
{
|
||||||
if(argc == 0)
|
if(argc == 0)
|
||||||
return true;
|
return true;
|
||||||
else if(argc == 1)
|
else if(argc == 1)
|
||||||
{
|
{
|
||||||
addToTable(NetSocket::fromHandle(dAtoi(argv[0])));
|
addToTable(NetSocket::fromHandle(argv[0].getInt()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public:
|
||||||
void disconnect();
|
void disconnect();
|
||||||
State getState() { return mState; }
|
State getState() { return mState; }
|
||||||
|
|
||||||
bool processArguments(S32 argc, ConsoleValueRef *argv);
|
bool processArguments(S32 argc, ConsoleValue *argv);
|
||||||
void send(const U8 *buffer, U32 bufferLen);
|
void send(const U8 *buffer, U32 bufferLen);
|
||||||
|
|
||||||
///Send an entire file over tcp
|
///Send an entire file over tcp
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ SimXMLDocument::~SimXMLDocument()
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Included for completeness.
|
// Included for completeness.
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
bool SimXMLDocument::processArguments(S32 argc, ConsoleValueRef *argv)
|
bool SimXMLDocument::processArguments(S32 argc, ConsoleValue *argv)
|
||||||
{
|
{
|
||||||
return argc == 0;
|
return argc == 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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, ConsoleValueRef *argv);
|
bool processArguments(S32 argc, ConsoleValue *argv);
|
||||||
bool onAdd();
|
bool onAdd();
|
||||||
void onRemove();
|
void onRemove();
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,15 @@ enum TypeReq
|
||||||
TypeReqNone,
|
TypeReqNone,
|
||||||
TypeReqUInt,
|
TypeReqUInt,
|
||||||
TypeReqFloat,
|
TypeReqFloat,
|
||||||
TypeReqString,
|
TypeReqString
|
||||||
TypeReqVar
|
};
|
||||||
|
|
||||||
|
enum ExprNodeName
|
||||||
|
{
|
||||||
|
NameExprNode,
|
||||||
|
NameFloatNode,
|
||||||
|
NameIntNode,
|
||||||
|
NameVarNode
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Representation of a node for the scripting language parser.
|
/// Representation of a node for the scripting language parser.
|
||||||
|
|
@ -52,7 +59,7 @@ enum TypeReq
|
||||||
/// each representing a different language construct.
|
/// each representing a different language construct.
|
||||||
struct StmtNode
|
struct StmtNode
|
||||||
{
|
{
|
||||||
StmtNode *mNext; ///< Next entry in parse tree.
|
StmtNode* next; ///< Next entry in parse tree.
|
||||||
|
|
||||||
StmtNode();
|
StmtNode();
|
||||||
virtual ~StmtNode() {}
|
virtual ~StmtNode() {}
|
||||||
|
|
@ -62,7 +69,7 @@ struct StmtNode
|
||||||
|
|
||||||
///
|
///
|
||||||
void append(StmtNode* next);
|
void append(StmtNode* next);
|
||||||
StmtNode *getNext() const { return mNext; }
|
StmtNode* getNext() const { return next; }
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
@ -92,7 +99,7 @@ struct StmtNode
|
||||||
|
|
||||||
/// Helper macro
|
/// Helper macro
|
||||||
#ifndef DEBUG_AST_NODES
|
#ifndef DEBUG_AST_NODES
|
||||||
# define DBG_STMT_TYPE(s) virtual String dbgStmtType() const { return String(#s); }
|
# define DBG_STMT_TYPE(s) virtual const char* dbgStmtType() const { return "#s"; }
|
||||||
#else
|
#else
|
||||||
# define DBG_STMT_TYPE(s)
|
# define DBG_STMT_TYPE(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -117,11 +124,13 @@ struct ContinueStmtNode : StmtNode
|
||||||
/// A mathematical expression.
|
/// A mathematical expression.
|
||||||
struct ExprNode : StmtNode
|
struct ExprNode : StmtNode
|
||||||
{
|
{
|
||||||
|
ExprNode* optimizedNode;
|
||||||
|
|
||||||
U32 compileStmt(CodeStream& codeStream, U32 ip);
|
U32 compileStmt(CodeStream& codeStream, U32 ip);
|
||||||
|
|
||||||
virtual U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) = 0;
|
virtual U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) = 0;
|
||||||
virtual TypeReq getPreferredType() = 0;
|
virtual TypeReq getPreferredType() = 0;
|
||||||
|
virtual ExprNodeName getExprNodeNameEnum() const { return NameExprNode; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReturnStmtNode : StmtNode
|
struct ReturnStmtNode : StmtNode
|
||||||
|
|
@ -205,6 +214,9 @@ struct FloatBinaryExprNode : BinaryExprNode
|
||||||
static FloatBinaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right);
|
static FloatBinaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right);
|
||||||
|
|
||||||
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
||||||
|
|
||||||
|
bool optimize();
|
||||||
|
|
||||||
TypeReq getPreferredType();
|
TypeReq getPreferredType();
|
||||||
DBG_STMT_TYPE(FloatBinaryExprNode);
|
DBG_STMT_TYPE(FloatBinaryExprNode);
|
||||||
};
|
};
|
||||||
|
|
@ -231,6 +243,8 @@ struct IntBinaryExprNode : BinaryExprNode
|
||||||
|
|
||||||
void getSubTypeOperand();
|
void getSubTypeOperand();
|
||||||
|
|
||||||
|
bool optimize();
|
||||||
|
|
||||||
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
||||||
TypeReq getPreferredType();
|
TypeReq getPreferredType();
|
||||||
DBG_STMT_TYPE(IntBinaryExprNode);
|
DBG_STMT_TYPE(IntBinaryExprNode);
|
||||||
|
|
@ -300,6 +314,7 @@ struct VarNode : ExprNode
|
||||||
|
|
||||||
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
||||||
TypeReq getPreferredType();
|
TypeReq getPreferredType();
|
||||||
|
virtual ExprNodeName getExprNodeNameEnum() const { return NameVarNode; }
|
||||||
DBG_STMT_TYPE(VarNode);
|
DBG_STMT_TYPE(VarNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -312,6 +327,7 @@ struct IntNode : ExprNode
|
||||||
|
|
||||||
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
||||||
TypeReq getPreferredType();
|
TypeReq getPreferredType();
|
||||||
|
virtual ExprNodeName getExprNodeNameEnum() const { return NameIntNode; }
|
||||||
DBG_STMT_TYPE(IntNode);
|
DBG_STMT_TYPE(IntNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -324,6 +340,7 @@ struct FloatNode : ExprNode
|
||||||
|
|
||||||
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
|
||||||
TypeReq getPreferredType();
|
TypeReq getPreferredType();
|
||||||
|
virtual ExprNodeName getExprNodeNameEnum() const { return NameFloatNode; }
|
||||||
DBG_STMT_TYPE(FloatNode);
|
DBG_STMT_TYPE(FloatNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -435,6 +452,7 @@ struct FuncCallExprNode : ExprNode
|
||||||
U32 callType;
|
U32 callType;
|
||||||
enum {
|
enum {
|
||||||
FunctionCall,
|
FunctionCall,
|
||||||
|
StaticCall,
|
||||||
MethodCall,
|
MethodCall,
|
||||||
ParentCall
|
ParentCall
|
||||||
};
|
};
|
||||||
|
|
@ -446,18 +464,6 @@ struct FuncCallExprNode : ExprNode
|
||||||
DBG_STMT_TYPE(FuncCallExprNode);
|
DBG_STMT_TYPE(FuncCallExprNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FuncPointerCallExprNode : ExprNode
|
|
||||||
{
|
|
||||||
ExprNode *funcPointer;
|
|
||||||
ExprNode *args;
|
|
||||||
|
|
||||||
static FuncPointerCallExprNode *alloc(S32 lineNumber, ExprNode *stmt, ExprNode *args);
|
|
||||||
|
|
||||||
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
|
|
||||||
TypeReq getPreferredType();
|
|
||||||
DBG_STMT_TYPE(FuncPointerCallExprNode);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AssertCallExprNode : ExprNode
|
struct AssertCallExprNode : ExprNode
|
||||||
{
|
{
|
||||||
ExprNode* testExpr;
|
ExprNode* testExpr;
|
||||||
|
|
@ -587,8 +593,6 @@ struct FunctionDeclStmtNode : StmtNode
|
||||||
};
|
};
|
||||||
|
|
||||||
extern StmtNode* gStatementList;
|
extern StmtNode* gStatementList;
|
||||||
extern StmtNode *gAnonFunctionList;
|
|
||||||
extern U32 gAnonFunctionID;
|
|
||||||
extern ExprEvalState gEvalState;
|
extern ExprEvalState gEvalState;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (c) 2012 GarageGames, LLC
|
// Copyright (c) 2013 GarageGames, LLC
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to
|
// of this software and associated documentation files (the "Software"), to
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "platform/platform.h"
|
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "console/compiler.h"
|
#include "console/compiler.h"
|
||||||
#include "console/consoleInternal.h"
|
#include "console/consoleInternal.h"
|
||||||
|
|
@ -116,6 +115,7 @@ FloatBinaryExprNode *FloatBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode
|
||||||
FloatBinaryExprNode* ret = (FloatBinaryExprNode*)consoleAlloc(sizeof(FloatBinaryExprNode));
|
FloatBinaryExprNode* ret = (FloatBinaryExprNode*)consoleAlloc(sizeof(FloatBinaryExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
|
|
||||||
ret->op = op;
|
ret->op = op;
|
||||||
ret->left = left;
|
ret->left = left;
|
||||||
|
|
@ -129,6 +129,7 @@ IntBinaryExprNode *IntBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *le
|
||||||
IntBinaryExprNode* ret = (IntBinaryExprNode*)consoleAlloc(sizeof(IntBinaryExprNode));
|
IntBinaryExprNode* ret = (IntBinaryExprNode*)consoleAlloc(sizeof(IntBinaryExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
|
|
||||||
ret->op = op;
|
ret->op = op;
|
||||||
ret->left = left;
|
ret->left = left;
|
||||||
|
|
@ -142,6 +143,7 @@ StreqExprNode *StreqExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *ri
|
||||||
StreqExprNode* ret = (StreqExprNode*)consoleAlloc(sizeof(StreqExprNode));
|
StreqExprNode* ret = (StreqExprNode*)consoleAlloc(sizeof(StreqExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->left = left;
|
ret->left = left;
|
||||||
ret->right = right;
|
ret->right = right;
|
||||||
ret->eq = eq;
|
ret->eq = eq;
|
||||||
|
|
@ -149,11 +151,12 @@ StreqExprNode *StreqExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *ri
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
StrcatExprNode *StrcatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar)
|
StrcatExprNode* StrcatExprNode::alloc(S32 lineNumber, ExprNode* left, ExprNode* right, int appendChar)
|
||||||
{
|
{
|
||||||
StrcatExprNode* ret = (StrcatExprNode*)consoleAlloc(sizeof(StrcatExprNode));
|
StrcatExprNode* ret = (StrcatExprNode*)consoleAlloc(sizeof(StrcatExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->left = left;
|
ret->left = left;
|
||||||
ret->right = right;
|
ret->right = right;
|
||||||
ret->appendChar = appendChar;
|
ret->appendChar = appendChar;
|
||||||
|
|
@ -166,6 +169,7 @@ CommaCatExprNode *CommaCatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNo
|
||||||
CommaCatExprNode* ret = (CommaCatExprNode*)consoleAlloc(sizeof(CommaCatExprNode));
|
CommaCatExprNode* ret = (CommaCatExprNode*)consoleAlloc(sizeof(CommaCatExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->left = left;
|
ret->left = left;
|
||||||
ret->right = right;
|
ret->right = right;
|
||||||
|
|
||||||
|
|
@ -177,6 +181,7 @@ IntUnaryExprNode *IntUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *expr
|
||||||
IntUnaryExprNode* ret = (IntUnaryExprNode*)consoleAlloc(sizeof(IntUnaryExprNode));
|
IntUnaryExprNode* ret = (IntUnaryExprNode*)consoleAlloc(sizeof(IntUnaryExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->op = op;
|
ret->op = op;
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -187,6 +192,7 @@ FloatUnaryExprNode *FloatUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *
|
||||||
FloatUnaryExprNode* ret = (FloatUnaryExprNode*)consoleAlloc(sizeof(FloatUnaryExprNode));
|
FloatUnaryExprNode* ret = (FloatUnaryExprNode*)consoleAlloc(sizeof(FloatUnaryExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->op = op;
|
ret->op = op;
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -197,6 +203,7 @@ VarNode *VarNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arra
|
||||||
VarNode* ret = (VarNode*)consoleAlloc(sizeof(VarNode));
|
VarNode* ret = (VarNode*)consoleAlloc(sizeof(VarNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->varName = varName;
|
ret->varName = varName;
|
||||||
ret->arrayIndex = arrayIndex;
|
ret->arrayIndex = arrayIndex;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -207,6 +214,7 @@ IntNode *IntNode::alloc(S32 lineNumber, S32 value)
|
||||||
IntNode* ret = (IntNode*)consoleAlloc(sizeof(IntNode));
|
IntNode* ret = (IntNode*)consoleAlloc(sizeof(IntNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->value = value;
|
ret->value = value;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -216,6 +224,7 @@ ConditionalExprNode *ConditionalExprNode::alloc(S32 lineNumber, ExprNode *testEx
|
||||||
ConditionalExprNode* ret = (ConditionalExprNode*)consoleAlloc(sizeof(ConditionalExprNode));
|
ConditionalExprNode* ret = (ConditionalExprNode*)consoleAlloc(sizeof(ConditionalExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->testExpr = testExpr;
|
ret->testExpr = testExpr;
|
||||||
ret->trueExpr = trueExpr;
|
ret->trueExpr = trueExpr;
|
||||||
ret->falseExpr = falseExpr;
|
ret->falseExpr = falseExpr;
|
||||||
|
|
@ -229,6 +238,7 @@ FloatNode *FloatNode::alloc(S32 lineNumber, F64 value)
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
|
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->value = value;
|
ret->value = value;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -237,12 +247,15 @@ StrConstNode *StrConstNode::alloc(S32 lineNumber, char *str, bool tag, bool doc)
|
||||||
{
|
{
|
||||||
StrConstNode* ret = (StrConstNode*)consoleAlloc(sizeof(StrConstNode));
|
StrConstNode* ret = (StrConstNode*)consoleAlloc(sizeof(StrConstNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
|
S32 len = dStrlen(str);
|
||||||
|
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
dsize_t retStrLen = dStrlen(str) + 1;
|
ret->optimizedNode = NULL;
|
||||||
ret->str = (char *)consoleAlloc(retStrLen);
|
ret->str = (char*)consoleAlloc(len + 1);
|
||||||
ret->tag = tag;
|
ret->tag = tag;
|
||||||
ret->doc = doc;
|
ret->doc = doc;
|
||||||
dStrcpy(ret->str, str, retStrLen);
|
dStrcpy(ret->str, str, len);
|
||||||
|
ret->str[len] = '\0';
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +265,7 @@ ConstantNode *ConstantNode::alloc(S32 lineNumber, StringTableEntry value)
|
||||||
ConstantNode* ret = (ConstantNode*)consoleAlloc(sizeof(ConstantNode));
|
ConstantNode* ret = (ConstantNode*)consoleAlloc(sizeof(ConstantNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->value = value;
|
ret->value = value;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -261,6 +275,7 @@ AssignExprNode *AssignExprNode::alloc(S32 lineNumber, StringTableEntry varName,
|
||||||
AssignExprNode* ret = (AssignExprNode*)consoleAlloc(sizeof(AssignExprNode));
|
AssignExprNode* ret = (AssignExprNode*)consoleAlloc(sizeof(AssignExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->varName = varName;
|
ret->varName = varName;
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
ret->arrayIndex = arrayIndex;
|
ret->arrayIndex = arrayIndex;
|
||||||
|
|
@ -273,6 +288,7 @@ AssignOpExprNode *AssignOpExprNode::alloc(S32 lineNumber, StringTableEntry varNa
|
||||||
AssignOpExprNode* ret = (AssignOpExprNode*)consoleAlloc(sizeof(AssignOpExprNode));
|
AssignOpExprNode* ret = (AssignOpExprNode*)consoleAlloc(sizeof(AssignOpExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->varName = varName;
|
ret->varName = varName;
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
ret->arrayIndex = arrayIndex;
|
ret->arrayIndex = arrayIndex;
|
||||||
|
|
@ -296,6 +312,7 @@ TTagDerefNode *TTagDerefNode::alloc(S32 lineNumber, ExprNode *expr)
|
||||||
TTagDerefNode* ret = (TTagDerefNode*)consoleAlloc(sizeof(TTagDerefNode));
|
TTagDerefNode* ret = (TTagDerefNode*)consoleAlloc(sizeof(TTagDerefNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -305,6 +322,7 @@ TTagExprNode *TTagExprNode::alloc(S32 lineNumber, StringTableEntry tag)
|
||||||
TTagExprNode* ret = (TTagExprNode*)consoleAlloc(sizeof(TTagExprNode));
|
TTagExprNode* ret = (TTagExprNode*)consoleAlloc(sizeof(TTagExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->tag = tag;
|
ret->tag = tag;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -314,28 +332,21 @@ FuncCallExprNode *FuncCallExprNode::alloc(S32 lineNumber, StringTableEntry funcN
|
||||||
FuncCallExprNode* ret = (FuncCallExprNode*)consoleAlloc(sizeof(FuncCallExprNode));
|
FuncCallExprNode* ret = (FuncCallExprNode*)consoleAlloc(sizeof(FuncCallExprNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->funcName = funcName;
|
ret->funcName = funcName;
|
||||||
ret->nameSpace = nameSpace;
|
ret->nameSpace = nameSpace;
|
||||||
ret->args = args;
|
ret->args = args;
|
||||||
if (dot)
|
if (dot)
|
||||||
ret->callType = MethodCall;
|
ret->callType = MethodCall;
|
||||||
else
|
else if (nameSpace != NULL)
|
||||||
{
|
{
|
||||||
if (nameSpace && !dStricmp(nameSpace, "Parent"))
|
if (dStricmp(nameSpace, "Parent") == 0)
|
||||||
ret->callType = ParentCall;
|
ret->callType = ParentCall;
|
||||||
|
else
|
||||||
|
ret->callType = StaticCall;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ret->callType = FunctionCall;
|
ret->callType = FunctionCall;
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
FuncPointerCallExprNode *FuncPointerCallExprNode::alloc(S32 lineNumber, ExprNode *funcPointer, ExprNode *args)
|
|
||||||
{
|
|
||||||
FuncPointerCallExprNode *ret = (FuncPointerCallExprNode *)consoleAlloc(sizeof(FuncPointerCallExprNode));
|
|
||||||
constructInPlace(ret);
|
|
||||||
ret->dbgLineNumber = lineNumber;
|
|
||||||
ret->funcPointer = funcPointer;
|
|
||||||
ret->args = args;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,6 +372,7 @@ SlotAccessNode *SlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, Expr
|
||||||
{
|
{
|
||||||
SlotAccessNode* ret = (SlotAccessNode*)consoleAlloc(sizeof(SlotAccessNode));
|
SlotAccessNode* ret = (SlotAccessNode*)consoleAlloc(sizeof(SlotAccessNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
ret->objectExpr = objectExpr;
|
ret->objectExpr = objectExpr;
|
||||||
ret->arrayExpr = arrayExpr;
|
ret->arrayExpr = arrayExpr;
|
||||||
|
|
@ -373,6 +385,7 @@ InternalSlotAccessNode *InternalSlotAccessNode::alloc(S32 lineNumber, ExprNode *
|
||||||
InternalSlotAccessNode* ret = (InternalSlotAccessNode*)consoleAlloc(sizeof(InternalSlotAccessNode));
|
InternalSlotAccessNode* ret = (InternalSlotAccessNode*)consoleAlloc(sizeof(InternalSlotAccessNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->objectExpr = objectExpr;
|
ret->objectExpr = objectExpr;
|
||||||
ret->slotExpr = slotExpr;
|
ret->slotExpr = slotExpr;
|
||||||
ret->recurse = recurse;
|
ret->recurse = recurse;
|
||||||
|
|
@ -384,6 +397,7 @@ SlotAssignNode *SlotAssignNode::alloc(S32 lineNumber, ExprNode *objectExpr, Expr
|
||||||
SlotAssignNode* ret = (SlotAssignNode*)consoleAlloc(sizeof(SlotAssignNode));
|
SlotAssignNode* ret = (SlotAssignNode*)consoleAlloc(sizeof(SlotAssignNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->objectExpr = objectExpr;
|
ret->objectExpr = objectExpr;
|
||||||
ret->arrayExpr = arrayExpr;
|
ret->arrayExpr = arrayExpr;
|
||||||
ret->slotName = slotName;
|
ret->slotName = slotName;
|
||||||
|
|
@ -397,6 +411,7 @@ SlotAssignOpNode *SlotAssignOpNode::alloc(S32 lineNumber, ExprNode *objectExpr,
|
||||||
SlotAssignOpNode* ret = (SlotAssignOpNode*)consoleAlloc(sizeof(SlotAssignOpNode));
|
SlotAssignOpNode* ret = (SlotAssignOpNode*)consoleAlloc(sizeof(SlotAssignOpNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->objectExpr = objectExpr;
|
ret->objectExpr = objectExpr;
|
||||||
ret->arrayExpr = arrayExpr;
|
ret->arrayExpr = arrayExpr;
|
||||||
ret->slotName = slotName;
|
ret->slotName = slotName;
|
||||||
|
|
@ -410,6 +425,7 @@ ObjectDeclNode *ObjectDeclNode::alloc(S32 lineNumber, ExprNode *classNameExpr, E
|
||||||
ObjectDeclNode* ret = (ObjectDeclNode*)consoleAlloc(sizeof(ObjectDeclNode));
|
ObjectDeclNode* ret = (ObjectDeclNode*)consoleAlloc(sizeof(ObjectDeclNode));
|
||||||
constructInPlace(ret);
|
constructInPlace(ret);
|
||||||
ret->dbgLineNumber = lineNumber;
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
ret->classNameExpr = classNameExpr;
|
ret->classNameExpr = classNameExpr;
|
||||||
ret->objectNameExpr = objectNameExpr;
|
ret->objectNameExpr = objectNameExpr;
|
||||||
ret->argList = argList;
|
ret->argList = argList;
|
||||||
|
|
@ -422,7 +438,7 @@ ObjectDeclNode *ObjectDeclNode::alloc(S32 lineNumber, ExprNode *classNameExpr, E
|
||||||
if (parentObject)
|
if (parentObject)
|
||||||
ret->parentObject = parentObject;
|
ret->parentObject = parentObject;
|
||||||
else
|
else
|
||||||
ret->parentObject = StringTable->EmptyString();
|
ret->parentObject = StringTable->insert("");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,85 +50,57 @@ namespace Compiler
|
||||||
ip = walk->compileStmt(codeStream, ip);
|
ip = walk->compileStmt(codeStream, ip);
|
||||||
return codeStream.tell();
|
return codeStream.tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isSimpleVarLookup(ExprNode *arrayExpr, StringTableEntry &varName)
|
|
||||||
{
|
|
||||||
if (arrayExpr == nullptr)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert("");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No double arrays allowed for optimization.
|
|
||||||
VarNode *var = dynamic_cast<VarNode*>(arrayExpr);
|
|
||||||
if (var && !var->arrayIndex)
|
|
||||||
{
|
|
||||||
StringTableEntry arrayVar = StringTable->insert(var->varName);
|
|
||||||
precompileIdent(arrayVar);
|
|
||||||
varName = arrayVar;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not allow 'recursive' %this optimizations. It can lead to weird bytecode
|
|
||||||
// generation since we can only optimize one expression at a time.
|
|
||||||
static bool OnlyOneThisOptimization = false;
|
|
||||||
|
|
||||||
inline bool isThisVar(ExprNode *objectExpr)
|
|
||||||
{
|
|
||||||
// If we are currently optimizing a this var, don't allow extra optimization.
|
|
||||||
if (objectExpr == nullptr || OnlyOneThisOptimization)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
VarNode *thisVar = dynamic_cast<VarNode*>(objectExpr);
|
|
||||||
if (thisVar && thisVar->varName == StringTable->insert("%this"))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void optimizeThisPointer(CodeStream &codeStream, ExprNode *arrayExpr, U32 &ip, StringTableEntry slotName)
|
|
||||||
{
|
|
||||||
OnlyOneThisOptimization = true;
|
|
||||||
|
|
||||||
// Is the array a simple variable? If so, we can optimize that.
|
|
||||||
StringTableEntry varName = nullptr;
|
|
||||||
bool simple = false;
|
|
||||||
|
|
||||||
if (arrayExpr)
|
|
||||||
{
|
|
||||||
simple = isSimpleVarLookup(arrayExpr, varName);
|
|
||||||
if (!simple)
|
|
||||||
{
|
|
||||||
// Less optimized array setting.
|
|
||||||
codeStream.emit(OP_ADVANCE_STR);
|
|
||||||
ip = arrayExpr->compile(codeStream, ip, TypeReqString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
codeStream.emit(OP_SETCURFIELD_THIS);
|
|
||||||
codeStream.emitSTE(slotName);
|
|
||||||
|
|
||||||
if (arrayExpr)
|
|
||||||
{
|
|
||||||
if (simple)
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_SETCURFIELD_ARRAY_VAR);
|
|
||||||
codeStream.emitSTE(varName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_SETCURFIELD_ARRAY);
|
|
||||||
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OnlyOneThisOptimization = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Compiler;
|
using namespace Compiler;
|
||||||
|
|
||||||
|
class FuncVars
|
||||||
|
{
|
||||||
|
struct Var
|
||||||
|
{
|
||||||
|
S32 reg;
|
||||||
|
TypeReq currentType;
|
||||||
|
bool isConstant;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
S32 assign(StringTableEntry var, TypeReq currentType, bool isConstant = false)
|
||||||
|
{
|
||||||
|
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
|
||||||
|
if (found != vars.end())
|
||||||
|
{
|
||||||
|
AssertISV(!found->second.isConstant, avar("Reassigning variable %s when it is a constant", var));
|
||||||
|
return found->second.reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 id = counter++;
|
||||||
|
vars[var] = { id, currentType, isConstant };
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 lookup(StringTableEntry var)
|
||||||
|
{
|
||||||
|
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
|
||||||
|
AssertISV(found != vars.end(), avar("Variable %s referenced before used when compiling script.", var));
|
||||||
|
return found->second.reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeReq lookupType(StringTableEntry var)
|
||||||
|
{
|
||||||
|
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
|
||||||
|
AssertISV(found != vars.end(), avar("Variable %s referenced before used when compiling script.", var));
|
||||||
|
return found->second.currentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline S32 count() { return counter; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<StringTableEntry, Var> vars;
|
||||||
|
S32 counter = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
FuncVars* gFuncVars = NULL;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void StmtNode::addBreakLine(CodeStream& code)
|
void StmtNode::addBreakLine(CodeStream& code)
|
||||||
|
|
@ -140,9 +112,8 @@ void StmtNode::addBreakLine(CodeStream &code)
|
||||||
|
|
||||||
StmtNode::StmtNode()
|
StmtNode::StmtNode()
|
||||||
{
|
{
|
||||||
mNext = NULL;
|
next = NULL;
|
||||||
dbgFileName = CodeBlock::smCurrentParser->getCurrentFile();
|
dbgFileName = CodeBlock::smCurrentParser->getCurrentFile();
|
||||||
dbgLineNumber = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StmtNode::setPackage(StringTableEntry)
|
void StmtNode::setPackage(StringTableEntry)
|
||||||
|
|
@ -152,9 +123,9 @@ void StmtNode::setPackage(StringTableEntry)
|
||||||
void StmtNode::append(StmtNode* next)
|
void StmtNode::append(StmtNode* next)
|
||||||
{
|
{
|
||||||
StmtNode* walk = this;
|
StmtNode* walk = this;
|
||||||
while (walk->mNext)
|
while (walk->next)
|
||||||
walk = walk->mNext;
|
walk = walk->next;
|
||||||
walk->mNext = next;
|
walk->next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -181,8 +152,6 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
|
||||||
return OP_STR_TO_FLT;
|
return OP_STR_TO_FLT;
|
||||||
case TypeReqNone:
|
case TypeReqNone:
|
||||||
return OP_STR_TO_NONE;
|
return OP_STR_TO_NONE;
|
||||||
case TypeReqVar:
|
|
||||||
return OP_SAVEVAR_STR;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -197,8 +166,6 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
|
||||||
return OP_FLT_TO_STR;
|
return OP_FLT_TO_STR;
|
||||||
case TypeReqNone:
|
case TypeReqNone:
|
||||||
return OP_FLT_TO_NONE;
|
return OP_FLT_TO_NONE;
|
||||||
case TypeReqVar:
|
|
||||||
return OP_SAVEVAR_FLT;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -213,24 +180,6 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
|
||||||
return OP_UINT_TO_STR;
|
return OP_UINT_TO_STR;
|
||||||
case TypeReqNone:
|
case TypeReqNone:
|
||||||
return OP_UINT_TO_NONE;
|
return OP_UINT_TO_NONE;
|
||||||
case TypeReqVar:
|
|
||||||
return OP_SAVEVAR_UINT;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (src == TypeReqVar)
|
|
||||||
{
|
|
||||||
switch (dst)
|
|
||||||
{
|
|
||||||
case TypeReqUInt:
|
|
||||||
return OP_LOADVAR_UINT;
|
|
||||||
case TypeReqFloat:
|
|
||||||
return OP_LOADVAR_FLT;
|
|
||||||
case TypeReqString:
|
|
||||||
return OP_LOADVAR_STR;
|
|
||||||
case TypeReqNone:
|
|
||||||
return OP_COPYVAR_TO_NONE;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -530,6 +479,12 @@ TypeReq ConditionalExprNode::getPreferredType()
|
||||||
|
|
||||||
U32 FloatBinaryExprNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
U32 FloatBinaryExprNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
||||||
{
|
{
|
||||||
|
if (optimize())
|
||||||
|
{
|
||||||
|
ip = optimizedNode->compile(codeStream, ip, type);
|
||||||
|
return codeStream.tell();
|
||||||
|
}
|
||||||
|
|
||||||
ip = right->compile(codeStream, ip, TypeReqFloat);
|
ip = right->compile(codeStream, ip, TypeReqFloat);
|
||||||
ip = left->compile(codeStream, ip, TypeReqFloat);
|
ip = left->compile(codeStream, ip, TypeReqFloat);
|
||||||
U32 operand = OP_INVALID;
|
U32 operand = OP_INVALID;
|
||||||
|
|
@ -619,6 +574,11 @@ void IntBinaryExprNode::getSubTypeOperand()
|
||||||
|
|
||||||
U32 IntBinaryExprNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
U32 IntBinaryExprNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
||||||
{
|
{
|
||||||
|
// TODO: What if we do other optimizations and this doesn't work for it..this
|
||||||
|
// so far only works for simple MOD optimizations...
|
||||||
|
if (optimize())
|
||||||
|
right = optimizedNode;
|
||||||
|
|
||||||
getSubTypeOperand();
|
getSubTypeOperand();
|
||||||
|
|
||||||
if (operand == OP_OR || operand == OP_AND)
|
if (operand == OP_OR || operand == OP_AND)
|
||||||
|
|
@ -767,13 +727,7 @@ TypeReq FloatUnaryExprNode::getPreferredType()
|
||||||
|
|
||||||
U32 VarNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
U32 VarNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
||||||
{
|
{
|
||||||
// if this has an arrayIndex and we are not short circuiting from a constant.
|
// if this has an arrayIndex...
|
||||||
// if we are a var node
|
|
||||||
// OP_SETCURVAR_ARRAY_VARLOOKUP
|
|
||||||
// varName
|
|
||||||
// varNodeVarName
|
|
||||||
|
|
||||||
// else
|
|
||||||
// OP_LOADIMMED_IDENT
|
// OP_LOADIMMED_IDENT
|
||||||
// varName
|
// varName
|
||||||
// OP_ADVANCE_STR
|
// OP_ADVANCE_STR
|
||||||
|
|
@ -790,54 +744,22 @@ U32 VarNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
if (type == TypeReqNone)
|
if (type == TypeReqNone)
|
||||||
return codeStream.tell();
|
return codeStream.tell();
|
||||||
|
|
||||||
bool shortCircuit = false;
|
|
||||||
if (arrayIndex)
|
|
||||||
{
|
|
||||||
// If we have a constant, shortcircuit the array logic.
|
|
||||||
|
|
||||||
IntNode *intNode = dynamic_cast<IntNode*>(arrayIndex);
|
|
||||||
StrConstNode *strNode = dynamic_cast<StrConstNode*>(arrayIndex);
|
|
||||||
if (intNode)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert(avar("%s%d", varName, intNode->value));
|
|
||||||
shortCircuit = true;
|
|
||||||
}
|
|
||||||
else if (strNode)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert(avar("%s%s", varName, strNode->str));
|
|
||||||
shortCircuit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
precompileIdent(varName);
|
precompileIdent(varName);
|
||||||
|
|
||||||
if (arrayIndex && !shortCircuit)
|
bool oldVariables = arrayIndex || varName[0] == '$';
|
||||||
|
|
||||||
|
if (oldVariables)
|
||||||
{
|
{
|
||||||
// Ok, lets try to optimize %var[%someothervar] as this is
|
codeStream.emit(arrayIndex ? OP_LOADIMMED_IDENT : OP_SETCURVAR);
|
||||||
// a common case for array usage.
|
|
||||||
StringTableEntry varNodeVarName;
|
|
||||||
if (isSimpleVarLookup(arrayIndex, varNodeVarName))
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_SETCURVAR_ARRAY_VARLOOKUP);
|
|
||||||
codeStream.emitSTE(varName);
|
codeStream.emitSTE(varName);
|
||||||
codeStream.emitSTE(varNodeVarName);
|
|
||||||
}
|
if (arrayIndex)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
codeStream.emit(OP_LOADIMMED_IDENT);
|
|
||||||
codeStream.emitSTE(varName);
|
|
||||||
codeStream.emit(OP_ADVANCE_STR);
|
codeStream.emit(OP_ADVANCE_STR);
|
||||||
ip = arrayIndex->compile(codeStream, ip, TypeReqString);
|
ip = arrayIndex->compile(codeStream, ip, TypeReqString);
|
||||||
codeStream.emit(OP_REWIND_STR);
|
codeStream.emit(OP_REWIND_STR);
|
||||||
codeStream.emit(OP_SETCURVAR_ARRAY);
|
codeStream.emit(OP_SETCURVAR_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_SETCURVAR);
|
|
||||||
codeStream.emitSTE(varName);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TypeReqUInt:
|
case TypeReqUInt:
|
||||||
|
|
@ -849,20 +771,31 @@ U32 VarNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
case TypeReqString:
|
case TypeReqString:
|
||||||
codeStream.emit(OP_LOADVAR_STR);
|
codeStream.emit(OP_LOADVAR_STR);
|
||||||
break;
|
break;
|
||||||
case TypeReqVar:
|
|
||||||
codeStream.emit(OP_LOADVAR_VAR);
|
|
||||||
break;
|
|
||||||
case TypeReqNone:
|
case TypeReqNone:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case TypeReqUInt: codeStream.emit(OP_LOAD_LOCAL_VAR_UINT); break;
|
||||||
|
case TypeReqFloat: codeStream.emit(OP_LOAD_LOCAL_VAR_FLT); break;
|
||||||
|
default: codeStream.emit(OP_LOAD_LOCAL_VAR_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
codeStream.emit(gFuncVars->lookup(varName));
|
||||||
|
}
|
||||||
|
|
||||||
return codeStream.tell();
|
return codeStream.tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeReq VarNode::getPreferredType()
|
TypeReq VarNode::getPreferredType()
|
||||||
{
|
{
|
||||||
return TypeReqNone; // no preferred type
|
bool oldVariables = arrayIndex || varName[0] == '$';
|
||||||
|
return oldVariables ? TypeReqNone : gFuncVars->lookupType(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
@ -1037,43 +970,17 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
if (subType == TypeReqNone)
|
if (subType == TypeReqNone)
|
||||||
subType = type;
|
subType = type;
|
||||||
if (subType == TypeReqNone)
|
if (subType == TypeReqNone)
|
||||||
{
|
|
||||||
// What we need to do in this case is turn it into a VarNode reference.
|
|
||||||
// Unfortunately other nodes such as field access (SlotAccessNode)
|
|
||||||
// cannot be optimized in the same manner as all fields are exposed
|
|
||||||
// and set as strings.
|
|
||||||
if (dynamic_cast<VarNode*>(expr) != NULL)
|
|
||||||
{
|
|
||||||
subType = TypeReqVar;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
subType = TypeReqString;
|
subType = TypeReqString;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if we are an array index and we are gonna short circuit
|
// if it's an array expr, the formula is:
|
||||||
// eval expr
|
|
||||||
// compute new varName
|
|
||||||
// OP_SETCURVAR_CREATE
|
|
||||||
// varName
|
|
||||||
// OP_SAVEVAR
|
|
||||||
|
|
||||||
//else if it's an array expr and we don't short circuit, the formula is:
|
|
||||||
// eval expr
|
// eval expr
|
||||||
// (push and pop if it's TypeReqString) OP_ADVANCE_STR
|
// (push and pop if it's TypeReqString) OP_ADVANCE_STR
|
||||||
// if array lookup is varnode
|
|
||||||
// OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP
|
|
||||||
// varName
|
|
||||||
// varNodeVarName
|
|
||||||
// else
|
|
||||||
// OP_LOADIMMED_IDENT
|
// OP_LOADIMMED_IDENT
|
||||||
// varName
|
// varName
|
||||||
// OP_ADVANCE_STR
|
// OP_ADVANCE_STR
|
||||||
// eval array
|
// eval array
|
||||||
// OP_REWIND_STR
|
// OP_REWIND_STR
|
||||||
// OP_SETCURVAR_ARRAY_CREATE
|
// OP_SETCURVAR_ARRAY_CREATE
|
||||||
// endif
|
|
||||||
// OP_TERMINATE_REWIND_STR
|
// OP_TERMINATE_REWIND_STR
|
||||||
// OP_SAVEVAR
|
// OP_SAVEVAR
|
||||||
|
|
||||||
|
|
@ -1083,45 +990,19 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
// varname
|
// varname
|
||||||
// OP_SAVEVAR
|
// OP_SAVEVAR
|
||||||
|
|
||||||
ip = expr->compile(codeStream, ip, subType);
|
|
||||||
|
|
||||||
bool shortCircuit = false;
|
|
||||||
if (arrayIndex)
|
|
||||||
{
|
|
||||||
// If we have a constant, shortcircuit the array logic.
|
|
||||||
|
|
||||||
IntNode *intNode = dynamic_cast<IntNode*>(arrayIndex);
|
|
||||||
StrConstNode *strNode = dynamic_cast<StrConstNode*>(arrayIndex);
|
|
||||||
if (intNode)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert(avar("%s%d", varName, intNode->value));
|
|
||||||
shortCircuit = true;
|
|
||||||
}
|
|
||||||
else if (strNode)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert(avar("%s%s", varName, strNode->str));
|
|
||||||
shortCircuit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
precompileIdent(varName);
|
precompileIdent(varName);
|
||||||
|
|
||||||
if (arrayIndex && !shortCircuit)
|
ip = expr->compile(codeStream, ip, subType);
|
||||||
|
|
||||||
|
bool oldVariables = arrayIndex || varName[0] == '$';
|
||||||
|
|
||||||
|
if (oldVariables)
|
||||||
|
{
|
||||||
|
if (arrayIndex)
|
||||||
{
|
{
|
||||||
if (subType == TypeReqString)
|
if (subType == TypeReqString)
|
||||||
codeStream.emit(OP_ADVANCE_STR);
|
codeStream.emit(OP_ADVANCE_STR);
|
||||||
|
|
||||||
// Ok, lets try to optimize %var[%someothervar] as this is
|
|
||||||
// a common case for array usage.
|
|
||||||
StringTableEntry varNodeVarName;
|
|
||||||
if (isSimpleVarLookup(arrayIndex, varNodeVarName))
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP);
|
|
||||||
codeStream.emitSTE(varName);
|
|
||||||
codeStream.emitSTE(varNodeVarName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_LOADIMMED_IDENT);
|
codeStream.emit(OP_LOADIMMED_IDENT);
|
||||||
codeStream.emitSTE(varName);
|
codeStream.emitSTE(varName);
|
||||||
|
|
||||||
|
|
@ -1129,8 +1010,6 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
ip = arrayIndex->compile(codeStream, ip, TypeReqString);
|
ip = arrayIndex->compile(codeStream, ip, TypeReqString);
|
||||||
codeStream.emit(OP_REWIND_STR);
|
codeStream.emit(OP_REWIND_STR);
|
||||||
codeStream.emit(OP_SETCURVAR_ARRAY_CREATE);
|
codeStream.emit(OP_SETCURVAR_ARRAY_CREATE);
|
||||||
}
|
|
||||||
|
|
||||||
if (subType == TypeReqString)
|
if (subType == TypeReqString)
|
||||||
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
||||||
}
|
}
|
||||||
|
|
@ -1141,23 +1020,27 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
}
|
}
|
||||||
switch (subType)
|
switch (subType)
|
||||||
{
|
{
|
||||||
case TypeReqString:
|
case TypeReqString: codeStream.emit(OP_SAVEVAR_STR); break;
|
||||||
codeStream.emit(OP_SAVEVAR_STR);
|
case TypeReqUInt: codeStream.emit(OP_SAVEVAR_UINT); break;
|
||||||
break;
|
case TypeReqFloat: codeStream.emit(OP_SAVEVAR_FLT); break;
|
||||||
case TypeReqUInt:
|
|
||||||
codeStream.emit(OP_SAVEVAR_UINT);
|
|
||||||
break;
|
|
||||||
case TypeReqFloat:
|
|
||||||
codeStream.emit(OP_SAVEVAR_FLT);
|
|
||||||
break;
|
|
||||||
case TypeReqVar:
|
|
||||||
codeStream.emit(OP_SAVEVAR_VAR);
|
|
||||||
break;
|
|
||||||
case TypeReqNone:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (subType)
|
||||||
|
{
|
||||||
|
case TypeReqUInt: codeStream.emit(OP_SAVE_LOCAL_VAR_UINT); break;
|
||||||
|
case TypeReqFloat: codeStream.emit(OP_SAVE_LOCAL_VAR_FLT); break;
|
||||||
|
default: codeStream.emit(OP_SAVE_LOCAL_VAR_STR);
|
||||||
|
}
|
||||||
|
codeStream.emit(gFuncVars->assign(varName, subType == TypeReqNone ? TypeReqString : subType));
|
||||||
|
}
|
||||||
|
|
||||||
if (type != subType)
|
if (type != subType)
|
||||||
codeStream.emit(conversionOp(subType, type));
|
{
|
||||||
|
U32 conOp = conversionOp(subType, type);
|
||||||
|
codeStream.emit(conOp);
|
||||||
|
}
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1178,7 +1061,6 @@ static void getAssignOpTypeOp(S32 op, TypeReq &type, U32 &operand)
|
||||||
operand = OP_ADD;
|
operand = OP_ADD;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
case opMINUSMINUS:
|
|
||||||
type = TypeReqFloat;
|
type = TypeReqFloat;
|
||||||
operand = OP_SUB;
|
operand = OP_SUB;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1221,112 +1103,49 @@ U32 AssignOpExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
{
|
{
|
||||||
|
|
||||||
// goes like this...
|
// goes like this...
|
||||||
//
|
|
||||||
// IF no array index && (op == OPPLUSPLUS or op == OPMINUSMINUS)
|
|
||||||
// if op == OPPLUSPLUS
|
|
||||||
// OP_INC
|
|
||||||
// varName
|
|
||||||
// else if op == OPMINUSMINUS
|
|
||||||
// OP_DEC
|
|
||||||
// varName
|
|
||||||
// else
|
|
||||||
// OP_INVALID
|
|
||||||
// endif
|
|
||||||
// ELSE
|
|
||||||
// eval expr as float or int
|
// eval expr as float or int
|
||||||
// if there's an arrayIndex and we don't short circuit
|
// if there's an arrayIndex
|
||||||
// if arrayIndex is a var node
|
|
||||||
// OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP
|
|
||||||
// varName
|
|
||||||
// varNodeVarName
|
|
||||||
// else
|
|
||||||
// OP_LOADIMMED_IDENT
|
// OP_LOADIMMED_IDENT
|
||||||
// varName
|
// varName
|
||||||
// OP_ADVANCE_STR
|
// OP_ADVANCE_STR
|
||||||
// eval arrayIndex stringwise
|
// eval arrayIndex stringwise
|
||||||
// OP_REWIND_STR
|
// OP_REWIND_STR
|
||||||
// OP_SETCURVAR_ARRAY_CREATE
|
// OP_SETCURVAR_ARRAY_CREATE
|
||||||
// endif
|
|
||||||
// else
|
// else
|
||||||
// OP_SETCURVAR_CREATE
|
// OP_SETCURVAR_CREATE
|
||||||
// varName
|
// varName
|
||||||
// endif
|
|
||||||
// OP_LOADVAR_FLT or UINT
|
// OP_LOADVAR_FLT or UINT
|
||||||
// operand
|
// operand
|
||||||
// OP_SAVEVAR_FLT or UINT
|
// OP_SAVEVAR_FLT or UINT
|
||||||
// ENDIF
|
|
||||||
//
|
|
||||||
// if subtype != type
|
|
||||||
// convert type
|
|
||||||
// endif
|
|
||||||
|
|
||||||
// conversion OP if necessary.
|
// conversion OP if necessary.
|
||||||
getAssignOpTypeOp(op, subType, operand);
|
getAssignOpTypeOp(op, subType, operand);
|
||||||
|
|
||||||
// ++ or -- optimization support for non indexed variables.
|
|
||||||
if ((!arrayIndex) && (op == opPLUSPLUS || op == opMINUSMINUS))
|
|
||||||
{
|
|
||||||
precompileIdent(varName);
|
precompileIdent(varName);
|
||||||
|
|
||||||
if (op == opPLUSPLUS)
|
bool oldVariables = arrayIndex || varName[0] == '$';
|
||||||
|
|
||||||
|
if (op == opPLUSPLUS && !oldVariables)
|
||||||
{
|
{
|
||||||
|
const S32 varIdx = gFuncVars->assign(varName, TypeReqFloat);
|
||||||
|
|
||||||
codeStream.emit(OP_INC);
|
codeStream.emit(OP_INC);
|
||||||
codeStream.emitSTE(varName);
|
codeStream.emit(varIdx);
|
||||||
}
|
|
||||||
else if (op == opMINUSMINUS)
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_DEC);
|
|
||||||
codeStream.emitSTE(varName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This should NEVER happen. This is just for sanity.
|
|
||||||
AssertISV(false, "Tried to use ++ or -- but something weird happened.");
|
|
||||||
codeStream.emit(OP_INVALID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ip = expr->compile(codeStream, ip, subType);
|
ip = expr->compile(codeStream, ip, subType);
|
||||||
|
|
||||||
bool shortCircuit = false;
|
if (oldVariables)
|
||||||
if (arrayIndex)
|
|
||||||
{
|
{
|
||||||
// If we have a constant, shortcircuit the array logic.
|
if (!arrayIndex)
|
||||||
|
|
||||||
IntNode *intNode = dynamic_cast<IntNode*>(arrayIndex);
|
|
||||||
StrConstNode *strNode = dynamic_cast<StrConstNode*>(arrayIndex);
|
|
||||||
if (intNode)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert(avar("%s%d", varName, intNode->value));
|
|
||||||
shortCircuit = true;
|
|
||||||
}
|
|
||||||
else if (strNode)
|
|
||||||
{
|
|
||||||
varName = StringTable->insert(avar("%s%s", varName, strNode->str));
|
|
||||||
shortCircuit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
precompileIdent(varName);
|
|
||||||
|
|
||||||
if (!arrayIndex || shortCircuit)
|
|
||||||
{
|
{
|
||||||
codeStream.emit(OP_SETCURVAR_CREATE);
|
codeStream.emit(OP_SETCURVAR_CREATE);
|
||||||
codeStream.emitSTE(varName);
|
codeStream.emitSTE(varName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// Ok, lets try to optimize %var[%someothervar] as this is
|
|
||||||
// a common case for array usage.
|
|
||||||
StringTableEntry varNodeVarName;
|
|
||||||
if (isSimpleVarLookup(arrayIndex, varNodeVarName))
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP);
|
|
||||||
codeStream.emitSTE(varName);
|
|
||||||
codeStream.emitSTE(varNodeVarName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
codeStream.emit(OP_LOADIMMED_IDENT);
|
codeStream.emit(OP_LOADIMMED_IDENT);
|
||||||
codeStream.emitSTE(varName);
|
codeStream.emitSTE(varName);
|
||||||
|
|
@ -1336,13 +1155,27 @@ U32 AssignOpExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
codeStream.emit(OP_REWIND_STR);
|
codeStream.emit(OP_REWIND_STR);
|
||||||
codeStream.emit(OP_SETCURVAR_ARRAY_CREATE);
|
codeStream.emit(OP_SETCURVAR_ARRAY_CREATE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
codeStream.emit((subType == TypeReqFloat) ? OP_LOADVAR_FLT : OP_LOADVAR_UINT);
|
codeStream.emit((subType == TypeReqFloat) ? OP_LOADVAR_FLT : OP_LOADVAR_UINT);
|
||||||
codeStream.emit(operand);
|
codeStream.emit(operand);
|
||||||
codeStream.emit((subType == TypeReqFloat) ? OP_SAVEVAR_FLT : OP_SAVEVAR_UINT);
|
codeStream.emit((subType == TypeReqFloat) ? OP_SAVEVAR_FLT : OP_SAVEVAR_UINT);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const bool isFloat = subType == TypeReqFloat;
|
||||||
|
const S32 varIdx = gFuncVars->assign(varName, subType == TypeReqNone ? TypeReqString : subType);
|
||||||
|
|
||||||
|
codeStream.emit(isFloat ? OP_LOAD_LOCAL_VAR_FLT : OP_LOAD_LOCAL_VAR_UINT);
|
||||||
|
codeStream.emit(varIdx);
|
||||||
|
codeStream.emit(operand);
|
||||||
|
codeStream.emit(isFloat ? OP_SAVE_LOCAL_VAR_FLT : OP_SAVE_LOCAL_VAR_UINT);
|
||||||
|
codeStream.emit(varIdx);
|
||||||
|
}
|
||||||
|
|
||||||
if (subType != type)
|
if (subType != type)
|
||||||
|
{
|
||||||
codeStream.emit(conversionOp(subType, type));
|
codeStream.emit(conversionOp(subType, type));
|
||||||
|
}
|
||||||
|
}
|
||||||
return codeStream.tell();
|
return codeStream.tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1399,38 +1232,19 @@ U32 FuncCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
precompileIdent(funcName);
|
precompileIdent(funcName);
|
||||||
precompileIdent(nameSpace);
|
precompileIdent(nameSpace);
|
||||||
|
|
||||||
|
S32 count = 0;
|
||||||
|
for (ExprNode* walk = args; walk; walk = static_cast<ExprNode*>(walk->getNext()))
|
||||||
|
count++;
|
||||||
|
|
||||||
codeStream.emit(OP_PUSH_FRAME);
|
codeStream.emit(OP_PUSH_FRAME);
|
||||||
|
codeStream.emit(count);
|
||||||
|
|
||||||
bool isThisCall = false;
|
for (ExprNode* walk = args; walk; walk = static_cast<ExprNode*>(walk->getNext()))
|
||||||
|
|
||||||
ExprNode *walk = args;
|
|
||||||
|
|
||||||
// Try to optimize the this pointer call if it is a variable
|
|
||||||
// that we are loading.
|
|
||||||
if (callType == MethodCall)
|
|
||||||
{
|
|
||||||
// We cannot optimize array indices because it can have quite
|
|
||||||
// a bit of code to figure out the array index.
|
|
||||||
VarNode *var = dynamic_cast<VarNode*>(args);
|
|
||||||
if (var && !var->arrayIndex)
|
|
||||||
{
|
|
||||||
precompileIdent(var->varName);
|
|
||||||
|
|
||||||
// Are we a %this call?
|
|
||||||
isThisCall = (var->varName == StringTable->insert("%this"));
|
|
||||||
|
|
||||||
codeStream.emit(OP_PUSH_THIS);
|
|
||||||
codeStream.emitSTE(var->varName);
|
|
||||||
|
|
||||||
// inc args since we took care of first arg.
|
|
||||||
walk = (ExprNode*)walk ->getNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; walk; walk = (ExprNode *)walk->getNext())
|
|
||||||
{
|
{
|
||||||
TypeReq walkType = walk->getPreferredType();
|
TypeReq walkType = walk->getPreferredType();
|
||||||
if (walkType == TypeReqNone) walkType = TypeReqString;
|
if (walkType == TypeReqNone)
|
||||||
|
walkType = TypeReqString;
|
||||||
|
|
||||||
ip = walk->compile(codeStream, ip, walkType);
|
ip = walk->compile(codeStream, ip, walkType);
|
||||||
switch (walk->getPreferredType())
|
switch (walk->getPreferredType())
|
||||||
{
|
{
|
||||||
|
|
@ -1446,22 +1260,10 @@ U32 FuncCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isThisCall)
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_CALLFUNC_THIS);
|
|
||||||
codeStream.emitSTE(funcName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (callType == MethodCall || callType == ParentCall)
|
|
||||||
codeStream.emit(OP_CALLFUNC);
|
codeStream.emit(OP_CALLFUNC);
|
||||||
else
|
|
||||||
codeStream.emit(OP_CALLFUNC_RESOLVE);
|
|
||||||
|
|
||||||
codeStream.emitSTE(funcName);
|
codeStream.emitSTE(funcName);
|
||||||
codeStream.emitSTE(nameSpace);
|
codeStream.emitSTE(nameSpace);
|
||||||
codeStream.emit(callType);
|
codeStream.emit(callType);
|
||||||
}
|
|
||||||
|
|
||||||
if (type != TypeReqString)
|
if (type != TypeReqString)
|
||||||
codeStream.emit(conversionOp(TypeReqString, type));
|
codeStream.emit(conversionOp(TypeReqString, type));
|
||||||
|
|
@ -1473,49 +1275,6 @@ TypeReq FuncCallExprNode::getPreferredType()
|
||||||
return TypeReqString;
|
return TypeReqString;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
U32 FuncPointerCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
|
||||||
{
|
|
||||||
// OP_PUSH_FRAME
|
|
||||||
// arg OP_PUSH arg OP_PUSH arg OP_PUSH
|
|
||||||
// eval all the args, then call the function.
|
|
||||||
|
|
||||||
// eval fn pointer
|
|
||||||
// OP_CALLFUNC_POINTER
|
|
||||||
|
|
||||||
codeStream.emit(OP_PUSH_FRAME);
|
|
||||||
for (ExprNode *walk = args; walk; walk = (ExprNode *)walk->getNext())
|
|
||||||
{
|
|
||||||
TypeReq walkType = walk->getPreferredType();
|
|
||||||
if (walkType == TypeReqNone) walkType = TypeReqString;
|
|
||||||
ip = walk->compile(codeStream, ip, walkType);
|
|
||||||
switch (walk->getPreferredType())
|
|
||||||
{
|
|
||||||
case TypeReqFloat:
|
|
||||||
codeStream.emit(OP_PUSH_FLT);
|
|
||||||
break;
|
|
||||||
case TypeReqUInt:
|
|
||||||
codeStream.emit(OP_PUSH_UINT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
codeStream.emit(OP_PUSH);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ip = funcPointer->compile(codeStream, ip, TypeReqString);
|
|
||||||
codeStream.emit(OP_CALLFUNC_POINTER);
|
|
||||||
|
|
||||||
if (type != TypeReqString)
|
|
||||||
codeStream.emit(conversionOp(TypeReqString, type));
|
|
||||||
return codeStream.tell();
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeReq FuncPointerCallExprNode::getPreferredType()
|
|
||||||
{
|
|
||||||
return TypeReqString;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -1548,13 +1307,6 @@ U32 SlotAccessNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
|
|
||||||
precompileIdent(slotName);
|
precompileIdent(slotName);
|
||||||
|
|
||||||
// check if object is %this. If we are, we can do additional optimizations.
|
|
||||||
if (isThisVar(objectExpr))
|
|
||||||
{
|
|
||||||
optimizeThisPointer(codeStream, arrayExpr, ip, slotName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (arrayExpr)
|
if (arrayExpr)
|
||||||
{
|
{
|
||||||
// eval array
|
// eval array
|
||||||
|
|
@ -1579,7 +1331,6 @@ U32 SlotAccessNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
||||||
codeStream.emit(OP_SETCURFIELD_ARRAY);
|
codeStream.emit(OP_SETCURFIELD_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
|
@ -1662,13 +1413,6 @@ U32 SlotAssignNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
precompileIdent(slotName);
|
precompileIdent(slotName);
|
||||||
|
|
||||||
ip = valueExpr->compile(codeStream, ip, TypeReqString);
|
ip = valueExpr->compile(codeStream, ip, TypeReqString);
|
||||||
|
|
||||||
if (isThisVar(objectExpr))
|
|
||||||
{
|
|
||||||
optimizeThisPointer(codeStream, arrayExpr, ip, slotName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
codeStream.emit(OP_ADVANCE_STR);
|
codeStream.emit(OP_ADVANCE_STR);
|
||||||
if (arrayExpr)
|
if (arrayExpr)
|
||||||
{
|
{
|
||||||
|
|
@ -1692,8 +1436,6 @@ U32 SlotAssignNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
}
|
}
|
||||||
|
|
||||||
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
||||||
}
|
|
||||||
|
|
||||||
codeStream.emit(OP_SAVEFIELD_STR);
|
codeStream.emit(OP_SAVEFIELD_STR);
|
||||||
|
|
||||||
if (typeID != -1)
|
if (typeID != -1)
|
||||||
|
|
@ -1743,13 +1485,6 @@ U32 SlotAssignOpNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
precompileIdent(slotName);
|
precompileIdent(slotName);
|
||||||
|
|
||||||
ip = valueExpr->compile(codeStream, ip, subType);
|
ip = valueExpr->compile(codeStream, ip, subType);
|
||||||
|
|
||||||
if (isThisVar(objectExpr))
|
|
||||||
{
|
|
||||||
optimizeThisPointer(codeStream, arrayExpr, ip, slotName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (arrayExpr)
|
if (arrayExpr)
|
||||||
{
|
{
|
||||||
ip = arrayExpr->compile(codeStream, ip, TypeReqString);
|
ip = arrayExpr->compile(codeStream, ip, TypeReqString);
|
||||||
|
|
@ -1765,7 +1500,6 @@ U32 SlotAssignOpNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
||||||
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
codeStream.emit(OP_TERMINATE_REWIND_STR);
|
||||||
codeStream.emit(OP_SETCURFIELD_ARRAY);
|
codeStream.emit(OP_SETCURFIELD_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
codeStream.emit((subType == TypeReqFloat) ? OP_LOADFIELD_FLT : OP_LOADFIELD_UINT);
|
codeStream.emit((subType == TypeReqFloat) ? OP_LOADFIELD_FLT : OP_LOADFIELD_UINT);
|
||||||
codeStream.emit(operand);
|
codeStream.emit(operand);
|
||||||
codeStream.emit((subType == TypeReqFloat) ? OP_SAVEFIELD_FLT : OP_SAVEFIELD_UINT);
|
codeStream.emit((subType == TypeReqFloat) ? OP_SAVEFIELD_FLT : OP_SAVEFIELD_UINT);
|
||||||
|
|
@ -1808,7 +1542,12 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root)
|
||||||
// To fix the stack issue [7/9/2007 Black]
|
// To fix the stack issue [7/9/2007 Black]
|
||||||
// OP_FINISH_OBJECT <-- fail point jumps to this opcode
|
// OP_FINISH_OBJECT <-- fail point jumps to this opcode
|
||||||
|
|
||||||
|
S32 count = 2; // 2 OP_PUSH's
|
||||||
|
for (ExprNode* exprWalk = argList; exprWalk; exprWalk = (ExprNode*)exprWalk->getNext())
|
||||||
|
count++;
|
||||||
|
|
||||||
codeStream.emit(OP_PUSH_FRAME);
|
codeStream.emit(OP_PUSH_FRAME);
|
||||||
|
codeStream.emit(count);
|
||||||
|
|
||||||
ip = classNameExpr->compile(codeStream, ip, TypeReqString);
|
ip = classNameExpr->compile(codeStream, ip, TypeReqString);
|
||||||
codeStream.emit(OP_PUSH);
|
codeStream.emit(OP_PUSH);
|
||||||
|
|
@ -1896,10 +1635,14 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
|
||||||
setCurrentStringTable(&getFunctionStringTable());
|
setCurrentStringTable(&getFunctionStringTable());
|
||||||
setCurrentFloatTable(&getFunctionFloatTable());
|
setCurrentFloatTable(&getFunctionFloatTable());
|
||||||
|
|
||||||
|
FuncVars vars;
|
||||||
|
gFuncVars = &vars;
|
||||||
|
|
||||||
argc = 0;
|
argc = 0;
|
||||||
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
||||||
{
|
{
|
||||||
precompileIdent(walk->varName);
|
precompileIdent(walk->varName);
|
||||||
|
gFuncVars->assign(walk->varName, TypeReqNone);
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1919,9 +1662,11 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
|
||||||
codeStream.emit(U32(bool(stmts != NULL) ? 1 : 0) + U32(dbgLineNumber << 1));
|
codeStream.emit(U32(bool(stmts != NULL) ? 1 : 0) + U32(dbgLineNumber << 1));
|
||||||
const U32 endIp = codeStream.emit(0);
|
const U32 endIp = codeStream.emit(0);
|
||||||
codeStream.emit(argc);
|
codeStream.emit(argc);
|
||||||
|
const U32 localNumVarsIP = codeStream.emit(0);
|
||||||
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
||||||
{
|
{
|
||||||
codeStream.emitSTE(walk->varName);
|
StringTableEntry name = walk->varName;
|
||||||
|
codeStream.emit(gFuncVars->lookup(name));
|
||||||
}
|
}
|
||||||
CodeBlock::smInFunction = true;
|
CodeBlock::smInFunction = true;
|
||||||
ip = compileBlock(stmts, codeStream, ip);
|
ip = compileBlock(stmts, codeStream, ip);
|
||||||
|
|
@ -1933,10 +1678,12 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
|
||||||
CodeBlock::smInFunction = false;
|
CodeBlock::smInFunction = false;
|
||||||
codeStream.emit(OP_RETURN_VOID);
|
codeStream.emit(OP_RETURN_VOID);
|
||||||
|
|
||||||
|
codeStream.patch(localNumVarsIP, gFuncVars->count());
|
||||||
codeStream.patch(endIp, codeStream.tell());
|
codeStream.patch(endIp, codeStream.tell());
|
||||||
|
|
||||||
setCurrentStringTable(&getGlobalStringTable());
|
setCurrentStringTable(&getGlobalStringTable());
|
||||||
setCurrentFloatTable(&getGlobalFloatTable());
|
setCurrentFloatTable(&getGlobalFloatTable());
|
||||||
|
gFuncVars = NULL;
|
||||||
|
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -477,7 +477,6 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
||||||
STEtoCode = compileSTEtoCode;
|
STEtoCode = compileSTEtoCode;
|
||||||
|
|
||||||
gStatementList = NULL;
|
gStatementList = NULL;
|
||||||
gAnonFunctionList = NULL;
|
|
||||||
|
|
||||||
// Set up the parser.
|
// Set up the parser.
|
||||||
smCurrentParser = getParserForFile(fileName);
|
smCurrentParser = getParserForFile(fileName);
|
||||||
|
|
@ -487,17 +486,6 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
||||||
smCurrentParser->setScanBuffer(script, fileName);
|
smCurrentParser->setScanBuffer(script, fileName);
|
||||||
smCurrentParser->restart(NULL);
|
smCurrentParser->restart(NULL);
|
||||||
smCurrentParser->parse();
|
smCurrentParser->parse();
|
||||||
if (gStatementList)
|
|
||||||
{
|
|
||||||
if (gAnonFunctionList)
|
|
||||||
{
|
|
||||||
// Prepend anonymous functions to statement list, so they're defined already when
|
|
||||||
// the statements run.
|
|
||||||
gAnonFunctionList->append(gStatementList);
|
|
||||||
gStatementList = gAnonFunctionList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (gSyntaxError)
|
if (gSyntaxError)
|
||||||
{
|
{
|
||||||
|
|
@ -575,11 +563,9 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
||||||
st.close();
|
st.close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
|
void CodeBlock::compileExec(StringTableEntry fileName, const char *inString, ConsoleValue &returnValue, bool noCalls, S32 setFrame)
|
||||||
{
|
{
|
||||||
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
|
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
|
||||||
|
|
||||||
|
|
@ -620,7 +606,6 @@ ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *in
|
||||||
addToCodeList();
|
addToCodeList();
|
||||||
|
|
||||||
gStatementList = NULL;
|
gStatementList = NULL;
|
||||||
gAnonFunctionList = NULL;
|
|
||||||
|
|
||||||
// Set up the parser.
|
// Set up the parser.
|
||||||
smCurrentParser = getParserForFile(fileName);
|
smCurrentParser = getParserForFile(fileName);
|
||||||
|
|
@ -630,21 +615,11 @@ ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *in
|
||||||
smCurrentParser->setScanBuffer(string, fileName);
|
smCurrentParser->setScanBuffer(string, fileName);
|
||||||
smCurrentParser->restart(NULL);
|
smCurrentParser->restart(NULL);
|
||||||
smCurrentParser->parse();
|
smCurrentParser->parse();
|
||||||
if (gStatementList)
|
|
||||||
{
|
|
||||||
if (gAnonFunctionList)
|
|
||||||
{
|
|
||||||
// Prepend anonymous functions to statement list, so they're defined already when
|
|
||||||
// the statements run.
|
|
||||||
gAnonFunctionList->append(gStatementList);
|
|
||||||
gStatementList = gAnonFunctionList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gStatementList)
|
if (!gStatementList)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
return ConsoleValueRef();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetTables();
|
resetTables();
|
||||||
|
|
@ -678,7 +653,7 @@ ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *in
|
||||||
if (lastIp + 1 != codeSize)
|
if (lastIp + 1 != codeSize)
|
||||||
Con::warnf(ConsoleLogEntry::General, "precompile size mismatch, precompile: %d compile: %d", codeSize, lastIp);
|
Con::warnf(ConsoleLogEntry::General, "precompile size mismatch, precompile: %d compile: %d", codeSize, lastIp);
|
||||||
|
|
||||||
return exec(0, fileName, NULL, 0, 0, noCalls, NULL, setFrame);
|
exec(0, fileName, NULL, 0, 0, noCalls, NULL, returnValue, setFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
@ -747,14 +722,15 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
bool hasBody = bool(code[ip + 6]);
|
bool hasBody = bool(code[ip + 6]);
|
||||||
U32 newIp = code[ip + 7];
|
U32 newIp = code[ip + 7];
|
||||||
U32 argc = code[ip + 8];
|
U32 argc = code[ip + 8];
|
||||||
|
U32 regCount = code[ip + 9];
|
||||||
endFuncIp = newIp;
|
endFuncIp = newIp;
|
||||||
|
|
||||||
Con::printf("%i: OP_FUNC_DECL name=%s nspace=%s package=%s hasbody=%i newip=%i argc=%i",
|
Con::printf("%i: OP_FUNC_DECL name=%s nspace=%s package=%s hasbody=%i newip=%i argc=%i regCount=%i",
|
||||||
ip - 1, fnName, fnNamespace, fnPackage, hasBody, newIp, argc);
|
ip - 1, fnName, fnNamespace, fnPackage, hasBody, newIp, argc, regCount);
|
||||||
|
|
||||||
// Skip args.
|
// Skip args.
|
||||||
|
|
||||||
ip += 9 + (argc * 2);
|
ip += 10 + argc;
|
||||||
smInFunction = true;
|
smInFunction = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1018,15 +994,8 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
|
|
||||||
case OP_INC:
|
case OP_INC:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_INC varName=%s", ip - 1, CodeToSTE(code, ip));
|
Con::printf("%i: OP_INC reg=%i", ip - 1, code[ip]);
|
||||||
ip += 2;
|
++ip;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_DEC:
|
|
||||||
{
|
|
||||||
Con::printf("%i: OP_DEC varName=%s", ip - 1, CodeToSTE(code, ip));
|
|
||||||
ip += 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1054,32 +1023,12 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SETCURVAR_ARRAY_VARLOOKUP:
|
|
||||||
{
|
|
||||||
StringTableEntry arrayName = CodeToSTE(code, ip);
|
|
||||||
StringTableEntry arrayLookup = CodeToSTE(code, ip + 2);
|
|
||||||
|
|
||||||
Con::printf("%i: OP_SETCURVAR_ARRAY_VARLOOKUP arrayName=%s arrayLookup=%s", ip - 1, arrayName, arrayLookup);
|
|
||||||
ip += 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_SETCURVAR_ARRAY_CREATE:
|
case OP_SETCURVAR_ARRAY_CREATE:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_SETCURVAR_ARRAY_CREATE", ip - 1);
|
Con::printf("%i: OP_SETCURVAR_ARRAY_CREATE", ip - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP:
|
|
||||||
{
|
|
||||||
StringTableEntry arrayName = CodeToSTE(code, ip);
|
|
||||||
StringTableEntry arrayLookup = CodeToSTE(code, ip + 2);
|
|
||||||
|
|
||||||
Con::printf("%i: OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP arrayName=%s arrayLookup=%s", ip - 1, arrayName, arrayLookup);
|
|
||||||
ip += 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_LOADVAR_UINT:
|
case OP_LOADVAR_UINT:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_LOADVAR_UINT", ip - 1);
|
Con::printf("%i: OP_LOADVAR_UINT", ip - 1);
|
||||||
|
|
@ -1098,12 +1047,6 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_LOADVAR_VAR:
|
|
||||||
{
|
|
||||||
Con::printf("%i: OP_LOADVAR_VAR", ip - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_SAVEVAR_UINT:
|
case OP_SAVEVAR_UINT:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_SAVEVAR_UINT", ip - 1);
|
Con::printf("%i: OP_SAVEVAR_UINT", ip - 1);
|
||||||
|
|
@ -1122,9 +1065,45 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SAVEVAR_VAR:
|
case OP_LOAD_LOCAL_VAR_UINT:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_SAVEVAR_VAR", ip - 1);
|
Con::printf("%i: OP_LOAD_LOCAL_VAR_UINT reg=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_LOAD_LOCAL_VAR_FLT:
|
||||||
|
{
|
||||||
|
Con::printf("%i: OP_LOAD_LOCAL_VAR_FLT reg=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_LOAD_LOCAL_VAR_STR:
|
||||||
|
{
|
||||||
|
Con::printf("%i: OP_LOAD_LOCAL_VAR_STR reg=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_SAVE_LOCAL_VAR_UINT:
|
||||||
|
{
|
||||||
|
Con::printf("%i: OP_SAVE_LOCAL_VAR_UINT reg=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_SAVE_LOCAL_VAR_FLT:
|
||||||
|
{
|
||||||
|
Con::printf("%i: OP_SAVE_LOCAL_VAR_FLT reg=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_SAVE_LOCAL_VAR_STR:
|
||||||
|
{
|
||||||
|
Con::printf("%i: OP_SAVE_LOCAL_VAR_STR reg=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1161,22 +1140,6 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SETCURFIELD_ARRAY_VAR:
|
|
||||||
{
|
|
||||||
StringTableEntry var = CodeToSTE(code, ip);
|
|
||||||
Con::printf("%i: OP_SETCURFIELD_ARRAY_VAR var=%s", ip - 1, var);
|
|
||||||
ip += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_SETCURFIELD_THIS:
|
|
||||||
{
|
|
||||||
StringTableEntry curField = CodeToSTE(code, ip);
|
|
||||||
Con::printf("%i: OP_SETCURFIELD_THIS field=%s", ip - 1, curField);
|
|
||||||
ip += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_SETCURFIELD_TYPE:
|
case OP_SETCURFIELD_TYPE:
|
||||||
{
|
{
|
||||||
U32 type = code[ip];
|
U32 type = code[ip];
|
||||||
|
|
@ -1259,7 +1222,7 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
|
|
||||||
case OP_UINT_TO_FLT:
|
case OP_UINT_TO_FLT:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_SAVEFIELD_STR", ip - 1);
|
Con::printf("%i: OP_UINT_TO_FLT", ip - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1275,12 +1238,6 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_COPYVAR_TO_NONE:
|
|
||||||
{
|
|
||||||
Con::printf("%i: OP_COPYVAR_TO_NONE", ip - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_LOADIMMED_UINT:
|
case OP_LOADIMMED_UINT:
|
||||||
{
|
{
|
||||||
U32 val = code[ip];
|
U32 val = code[ip];
|
||||||
|
|
@ -1329,49 +1286,27 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_CALLFUNC_RESOLVE:
|
|
||||||
{
|
|
||||||
StringTableEntry fnNamespace = CodeToSTE(code, ip + 2);
|
|
||||||
StringTableEntry fnName = CodeToSTE(code, ip);
|
|
||||||
U32 callType = code[ip + 2];
|
|
||||||
|
|
||||||
Con::printf("%i: OP_CALLFUNC_RESOLVE name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace,
|
|
||||||
callType == FuncCallExprNode::FunctionCall ? "FunctionCall"
|
|
||||||
: callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall");
|
|
||||||
|
|
||||||
ip += 5;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_CALLFUNC:
|
case OP_CALLFUNC:
|
||||||
{
|
{
|
||||||
StringTableEntry fnNamespace = CodeToSTE(code, ip + 2);
|
StringTableEntry fnNamespace = CodeToSTE(code, ip + 2);
|
||||||
StringTableEntry fnName = CodeToSTE(code, ip);
|
StringTableEntry fnName = CodeToSTE(code, ip);
|
||||||
U32 callType = code[ip + 4];
|
U32 callType = code[ip + 4];
|
||||||
|
|
||||||
Con::printf("%i: OP_CALLFUNC name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace,
|
StringTableEntry callTypeName;
|
||||||
callType == FuncCallExprNode::FunctionCall ? "FunctionCall"
|
switch (callType)
|
||||||
: callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall");
|
{
|
||||||
|
case FuncCallExprNode::FunctionCall: callTypeName = "FunctionCall"; break;
|
||||||
|
case FuncCallExprNode::MethodCall: callTypeName = "MethodCall"; break;
|
||||||
|
case FuncCallExprNode::ParentCall: callTypeName = "ParentCall"; break;
|
||||||
|
case FuncCallExprNode::StaticCall: callTypeName = "StaticCall"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con::printf("%i: OP_CALLFUNC name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, callTypeName);
|
||||||
|
|
||||||
ip += 5;
|
ip += 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_CALLFUNC_POINTER:
|
|
||||||
{
|
|
||||||
Con::printf("%i: OP_CALLFUNC_POINTER", ip - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_CALLFUNC_THIS:
|
|
||||||
{
|
|
||||||
StringTableEntry fnName = CodeToSTE(code, ip);
|
|
||||||
Con::printf("%i: OP_CALLFUNC_THIS name=%s ", ip - 1, fnName);
|
|
||||||
|
|
||||||
ip += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_ADVANCE_STR:
|
case OP_ADVANCE_STR:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_ADVANCE_STR", ip - 1);
|
Con::printf("%i: OP_ADVANCE_STR", ip - 1);
|
||||||
|
|
@ -1434,22 +1369,10 @@ void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_PUSH_VAR:
|
|
||||||
{
|
|
||||||
Con::printf("%i: OP_PUSH_VAR", ip - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_PUSH_THIS:
|
|
||||||
{
|
|
||||||
Con::printf("%i: OP_PUSH_THIS varName=%s", ip - 1, CodeToSTE(code, ip));
|
|
||||||
ip += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_PUSH_FRAME:
|
case OP_PUSH_FRAME:
|
||||||
{
|
{
|
||||||
Con::printf("%i: OP_PUSH_FRAME", ip - 1);
|
Con::printf("%i: OP_PUSH_FRAME count=%i", ip - 1, code[ip]);
|
||||||
|
++ip;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,262 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2012 GarageGames, LLC
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef _CODEINTERPRETER_H_
|
|
||||||
#define _CODEINTERPRETER_H_
|
|
||||||
|
|
||||||
#include "console/codeBlock.h"
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "console/consoleInternal.h"
|
|
||||||
|
|
||||||
/// Frame data for a foreach/foreach$ loop.
|
|
||||||
struct IterStackRecord
|
|
||||||
{
|
|
||||||
/// If true, this is a foreach$ loop; if not, it's a foreach loop.
|
|
||||||
bool mIsStringIter;
|
|
||||||
|
|
||||||
/// The iterator variable.
|
|
||||||
Dictionary::Entry* mVariable;
|
|
||||||
|
|
||||||
/// Information for an object iterator loop.
|
|
||||||
struct ObjectPos
|
|
||||||
{
|
|
||||||
/// The set being iterated over.
|
|
||||||
SimSet* mSet;
|
|
||||||
|
|
||||||
/// Current index in the set.
|
|
||||||
U32 mIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Information for a string iterator loop.
|
|
||||||
struct StringPos
|
|
||||||
{
|
|
||||||
/// The raw string data on the string stack.
|
|
||||||
StringStackPtr mString;
|
|
||||||
|
|
||||||
/// Current parsing position.
|
|
||||||
U32 mIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
ObjectPos mObj;
|
|
||||||
StringPos mStr;
|
|
||||||
} mData;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum OPCodeReturn
|
|
||||||
{
|
|
||||||
exitCode = -1,
|
|
||||||
success = 0,
|
|
||||||
breakContinue = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
class CodeInterpreter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CodeInterpreter(CodeBlock *cb);
|
|
||||||
~CodeInterpreter();
|
|
||||||
|
|
||||||
ConsoleValueRef exec(U32 ip,
|
|
||||||
StringTableEntry functionName,
|
|
||||||
Namespace *thisNamespace,
|
|
||||||
U32 argc,
|
|
||||||
ConsoleValueRef *argv,
|
|
||||||
bool noCalls,
|
|
||||||
StringTableEntry packageName,
|
|
||||||
S32 setFrame);
|
|
||||||
|
|
||||||
static void init();
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
private:
|
|
||||||
void parseArgs(U32 &ip);
|
|
||||||
|
|
||||||
/// Group op codes
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
OPCodeReturn op_func_decl(U32 &ip);
|
|
||||||
OPCodeReturn op_create_object(U32 &ip);
|
|
||||||
OPCodeReturn op_add_object(U32 &ip);
|
|
||||||
OPCodeReturn op_end_object(U32 &ip);
|
|
||||||
OPCodeReturn op_finish_object(U32 &ip);
|
|
||||||
OPCodeReturn op_jmpiffnot(U32 &ip);
|
|
||||||
OPCodeReturn op_jmpifnot(U32 &ip);
|
|
||||||
OPCodeReturn op_jmpiff(U32 &ip);
|
|
||||||
OPCodeReturn op_jmpif(U32 &ip);
|
|
||||||
OPCodeReturn op_jmpifnot_np(U32 &ip);
|
|
||||||
OPCodeReturn op_jmpif_np(U32 &ip);
|
|
||||||
OPCodeReturn op_jmp(U32 &ip);
|
|
||||||
OPCodeReturn op_return_void(U32 &ip);
|
|
||||||
OPCodeReturn op_return(U32 &ip);
|
|
||||||
OPCodeReturn op_return_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_return_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_cmpeq(U32 &ip);
|
|
||||||
OPCodeReturn op_cmpgr(U32 &ip);
|
|
||||||
OPCodeReturn op_cmpge(U32 &ip);
|
|
||||||
OPCodeReturn op_cmplt(U32 &ip);
|
|
||||||
OPCodeReturn op_cmple(U32 &ip);
|
|
||||||
OPCodeReturn op_cmpne(U32 &ip);
|
|
||||||
OPCodeReturn op_xor(U32 &ip);
|
|
||||||
OPCodeReturn op_mod(U32 &ip);
|
|
||||||
OPCodeReturn op_bitand(U32 &ip);
|
|
||||||
OPCodeReturn op_bitor(U32 &ip);
|
|
||||||
OPCodeReturn op_not(U32 &ip);
|
|
||||||
OPCodeReturn op_notf(U32 &ip);
|
|
||||||
OPCodeReturn op_onescomplement(U32 &ip);
|
|
||||||
OPCodeReturn op_shr(U32 &ip);
|
|
||||||
OPCodeReturn op_shl(U32 &ip);
|
|
||||||
OPCodeReturn op_and(U32 &ip);
|
|
||||||
OPCodeReturn op_or(U32 &ip);
|
|
||||||
OPCodeReturn op_add(U32 &ip);
|
|
||||||
OPCodeReturn op_sub(U32 &ip);
|
|
||||||
OPCodeReturn op_mul(U32 &ip);
|
|
||||||
OPCodeReturn op_div(U32 &ip);
|
|
||||||
OPCodeReturn op_neg(U32 &ip);
|
|
||||||
OPCodeReturn op_inc(U32 &ip);
|
|
||||||
OPCodeReturn op_dec(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurvar(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurvar_create(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurvar_array(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurvar_array_varlookup(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurvar_array_create(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurvar_array_create_varlookup(U32 &ip);
|
|
||||||
OPCodeReturn op_loadvar_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_loadvar_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_loadvar_str(U32 &ip);
|
|
||||||
OPCodeReturn op_loadvar_var(U32 &ip);
|
|
||||||
OPCodeReturn op_savevar_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_savevar_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_savevar_str(U32 &ip);
|
|
||||||
OPCodeReturn op_savevar_var(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurobject(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurobject_internal(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurobject_new(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurfield(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurfield_array(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurfield_type(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurfield_this(U32 &ip);
|
|
||||||
OPCodeReturn op_setcurfield_array_var(U32 &ip);
|
|
||||||
OPCodeReturn op_loadfield_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_loadfield_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_loadfield_str(U32 &ip);
|
|
||||||
OPCodeReturn op_savefield_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_savefield_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_savefield_str(U32 &ip);
|
|
||||||
OPCodeReturn op_str_to_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_str_to_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_str_to_none(U32 &ip);
|
|
||||||
OPCodeReturn op_flt_to_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_flt_to_str(U32 &ip);
|
|
||||||
OPCodeReturn op_flt_to_none(U32 &ip);
|
|
||||||
OPCodeReturn op_uint_to_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_uint_to_str(U32 &ip);
|
|
||||||
OPCodeReturn op_uint_to_none(U32 &ip);
|
|
||||||
OPCodeReturn op_copyvar_to_none(U32 &ip);
|
|
||||||
OPCodeReturn op_loadimmed_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_loadimmed_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_tag_to_str(U32 &ip);
|
|
||||||
OPCodeReturn op_loadimmed_str(U32 &ip);
|
|
||||||
OPCodeReturn op_docblock_str(U32 &ip);
|
|
||||||
OPCodeReturn op_loadimmed_ident(U32 &ip);
|
|
||||||
OPCodeReturn op_callfunc_resolve(U32 &ip);
|
|
||||||
OPCodeReturn op_callfunc(U32 &ip);
|
|
||||||
OPCodeReturn op_callfunc_pointer(U32 &ip);
|
|
||||||
OPCodeReturn op_callfunc_this(U32 &ip);
|
|
||||||
OPCodeReturn op_advance_str(U32 &ip);
|
|
||||||
OPCodeReturn op_advance_str_appendchar(U32 &ip);
|
|
||||||
OPCodeReturn op_advance_str_comma(U32 &ip);
|
|
||||||
OPCodeReturn op_advance_str_nul(U32 &ip);
|
|
||||||
OPCodeReturn op_rewind_str(U32 &ip);
|
|
||||||
OPCodeReturn op_terminate_rewind_str(U32 &ip);
|
|
||||||
OPCodeReturn op_compare_str(U32 &ip);
|
|
||||||
OPCodeReturn op_push(U32 &ip);
|
|
||||||
OPCodeReturn op_push_uint(U32 &ip);
|
|
||||||
OPCodeReturn op_push_flt(U32 &ip);
|
|
||||||
OPCodeReturn op_push_var(U32 &ip);
|
|
||||||
OPCodeReturn op_push_this(U32 &ip);
|
|
||||||
OPCodeReturn op_push_frame(U32 &ip);
|
|
||||||
OPCodeReturn op_assert(U32 &ip);
|
|
||||||
OPCodeReturn op_break(U32 &ip);
|
|
||||||
OPCodeReturn op_iter_begin_str(U32 &ip);
|
|
||||||
OPCodeReturn op_iter_begin(U32 &ip);
|
|
||||||
OPCodeReturn op_iter(U32 &ip);
|
|
||||||
OPCodeReturn op_iter_end(U32 &ip);
|
|
||||||
OPCodeReturn op_invalid(U32 &ip);
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CodeBlock *mCodeBlock;
|
|
||||||
|
|
||||||
/// Group exec arguments.
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
StringTableEntry functionName;
|
|
||||||
Namespace *thisNamespace;
|
|
||||||
U32 argc;
|
|
||||||
ConsoleValueRef *argv;
|
|
||||||
bool noCalls;
|
|
||||||
StringTableEntry packageName;
|
|
||||||
S32 setFrame;
|
|
||||||
} mExec;
|
|
||||||
|
|
||||||
U32 mIterDepth;
|
|
||||||
F64 *mCurFloatTable;
|
|
||||||
char *mCurStringTable;
|
|
||||||
StringTableEntry mThisFunctionName;
|
|
||||||
bool mPopFrame;
|
|
||||||
|
|
||||||
// Add local object creation stack [7/9/2007 Black]
|
|
||||||
static const U32 objectCreationStackSize = 32;
|
|
||||||
U32 mObjectCreationStackIndex;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
SimObject *newObject;
|
|
||||||
U32 failJump;
|
|
||||||
} mObjectCreationStack[objectCreationStackSize];
|
|
||||||
|
|
||||||
SimObject *mCurrentNewObject;
|
|
||||||
U32 mFailJump;
|
|
||||||
StringTableEntry mPrevField;
|
|
||||||
StringTableEntry mCurField;
|
|
||||||
SimObject *mPrevObject;
|
|
||||||
SimObject *mCurObject;
|
|
||||||
SimObject *mSaveObject;
|
|
||||||
SimObject *mThisObject;
|
|
||||||
Namespace::Entry *mNSEntry;
|
|
||||||
StringTableEntry mCurFNDocBlock;
|
|
||||||
StringTableEntry mCurNSDocBlock;
|
|
||||||
U32 mCallArgc;
|
|
||||||
ConsoleValueRef *mCallArgv;
|
|
||||||
CodeBlock *mSaveCodeBlock;
|
|
||||||
|
|
||||||
// note: anything returned is pushed to CSTK and will be invalidated on the next exec()
|
|
||||||
ConsoleValueRef mReturnValue;
|
|
||||||
|
|
||||||
U32 mCurrentInstruction;
|
|
||||||
|
|
||||||
static const S32 nsDocLength = 128;
|
|
||||||
char mNSDocBlockClass[nsDocLength];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -93,26 +93,28 @@ namespace Compiler
|
||||||
OP_MUL,
|
OP_MUL,
|
||||||
OP_DIV,
|
OP_DIV,
|
||||||
OP_NEG,
|
OP_NEG,
|
||||||
|
|
||||||
OP_INC,
|
OP_INC,
|
||||||
OP_DEC,
|
|
||||||
|
|
||||||
OP_SETCURVAR,
|
OP_SETCURVAR,
|
||||||
OP_SETCURVAR_CREATE,
|
OP_SETCURVAR_CREATE,
|
||||||
OP_SETCURVAR_ARRAY,
|
OP_SETCURVAR_ARRAY,
|
||||||
OP_SETCURVAR_ARRAY_VARLOOKUP,
|
|
||||||
OP_SETCURVAR_ARRAY_CREATE,
|
OP_SETCURVAR_ARRAY_CREATE,
|
||||||
OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP,
|
|
||||||
|
|
||||||
OP_LOADVAR_UINT,// 40
|
OP_LOADVAR_UINT,// 40
|
||||||
OP_LOADVAR_FLT,
|
OP_LOADVAR_FLT,
|
||||||
OP_LOADVAR_STR,
|
OP_LOADVAR_STR,
|
||||||
OP_LOADVAR_VAR,
|
|
||||||
|
|
||||||
OP_SAVEVAR_UINT,
|
OP_SAVEVAR_UINT,
|
||||||
OP_SAVEVAR_FLT,
|
OP_SAVEVAR_FLT,
|
||||||
OP_SAVEVAR_STR,
|
OP_SAVEVAR_STR,
|
||||||
OP_SAVEVAR_VAR,
|
|
||||||
|
OP_LOAD_LOCAL_VAR_UINT,
|
||||||
|
OP_LOAD_LOCAL_VAR_FLT,
|
||||||
|
OP_LOAD_LOCAL_VAR_STR,
|
||||||
|
|
||||||
|
OP_SAVE_LOCAL_VAR_UINT,
|
||||||
|
OP_SAVE_LOCAL_VAR_FLT,
|
||||||
|
OP_SAVE_LOCAL_VAR_STR,
|
||||||
|
|
||||||
OP_SETCUROBJECT,
|
OP_SETCUROBJECT,
|
||||||
OP_SETCUROBJECT_NEW,
|
OP_SETCUROBJECT_NEW,
|
||||||
|
|
@ -121,8 +123,6 @@ namespace Compiler
|
||||||
OP_SETCURFIELD,
|
OP_SETCURFIELD,
|
||||||
OP_SETCURFIELD_ARRAY, // 50
|
OP_SETCURFIELD_ARRAY, // 50
|
||||||
OP_SETCURFIELD_TYPE,
|
OP_SETCURFIELD_TYPE,
|
||||||
OP_SETCURFIELD_ARRAY_VAR,
|
|
||||||
OP_SETCURFIELD_THIS,
|
|
||||||
|
|
||||||
OP_LOADFIELD_UINT,
|
OP_LOADFIELD_UINT,
|
||||||
OP_LOADFIELD_FLT,
|
OP_LOADFIELD_FLT,
|
||||||
|
|
@ -141,19 +141,15 @@ namespace Compiler
|
||||||
OP_UINT_TO_FLT,
|
OP_UINT_TO_FLT,
|
||||||
OP_UINT_TO_STR,
|
OP_UINT_TO_STR,
|
||||||
OP_UINT_TO_NONE,
|
OP_UINT_TO_NONE,
|
||||||
OP_COPYVAR_TO_NONE,
|
|
||||||
|
|
||||||
OP_LOADIMMED_UINT,
|
OP_LOADIMMED_UINT,
|
||||||
OP_LOADIMMED_FLT,
|
OP_LOADIMMED_FLT,
|
||||||
OP_TAG_TO_STR,
|
OP_TAG_TO_STR,
|
||||||
OP_LOADIMMED_STR, // 70
|
OP_LOADIMMED_STR, // 70
|
||||||
OP_DOCBLOCK_STR,
|
OP_DOCBLOCK_STR, // 76
|
||||||
OP_LOADIMMED_IDENT,
|
OP_LOADIMMED_IDENT,
|
||||||
|
|
||||||
OP_CALLFUNC_RESOLVE,
|
|
||||||
OP_CALLFUNC,
|
OP_CALLFUNC,
|
||||||
OP_CALLFUNC_POINTER,
|
|
||||||
OP_CALLFUNC_THIS,
|
|
||||||
|
|
||||||
OP_ADVANCE_STR,
|
OP_ADVANCE_STR,
|
||||||
OP_ADVANCE_STR_APPENDCHAR,
|
OP_ADVANCE_STR_APPENDCHAR,
|
||||||
|
|
@ -166,8 +162,6 @@ namespace Compiler
|
||||||
OP_PUSH, // String
|
OP_PUSH, // String
|
||||||
OP_PUSH_UINT, // Integer
|
OP_PUSH_UINT, // Integer
|
||||||
OP_PUSH_FLT, // Float
|
OP_PUSH_FLT, // Float
|
||||||
OP_PUSH_VAR, // Variable
|
|
||||||
OP_PUSH_THIS, // This pointer
|
|
||||||
OP_PUSH_FRAME, // Frame
|
OP_PUSH_FRAME, // Frame
|
||||||
|
|
||||||
OP_ASSERT,
|
OP_ASSERT,
|
||||||
|
|
|
||||||
|
|
@ -271,8 +271,6 @@ StringTableEntry gCurrentFile;
|
||||||
StringTableEntry gCurrentRoot;
|
StringTableEntry gCurrentRoot;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
S32 gObjectCopyFailures = -1;
|
|
||||||
|
|
||||||
bool alwaysUseDebugOutput = true;
|
bool alwaysUseDebugOutput = true;
|
||||||
bool useTimestamp = false;
|
bool useTimestamp = false;
|
||||||
bool useRealTimestamp = false;
|
bool useRealTimestamp = false;
|
||||||
|
|
@ -327,6 +325,7 @@ void init()
|
||||||
|
|
||||||
// Setup the console types.
|
// Setup the console types.
|
||||||
ConsoleBaseType::initialize();
|
ConsoleBaseType::initialize();
|
||||||
|
ConsoleValue::init();
|
||||||
|
|
||||||
// And finally, the ACR...
|
// And finally, the ACR...
|
||||||
AbstractClassRep::initialize();
|
AbstractClassRep::initialize();
|
||||||
|
|
@ -344,10 +343,6 @@ void init()
|
||||||
addVariable( "instantGroup", TypeRealString, &gInstantGroup, "The group that objects will be added to when they are created.\n"
|
addVariable( "instantGroup", TypeRealString, &gInstantGroup, "The group that objects will be added to when they are created.\n"
|
||||||
"@ingroup Console\n");
|
"@ingroup Console\n");
|
||||||
|
|
||||||
addVariable("Con::objectCopyFailures", TypeS32, &gObjectCopyFailures, "If greater than zero then it counts the number of object creation "
|
|
||||||
"failures based on a missing copy object and does not report an error..\n"
|
|
||||||
"@ingroup Console\n");
|
|
||||||
|
|
||||||
// Current script file name and root
|
// Current script file name and root
|
||||||
addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n"
|
addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n"
|
||||||
"@ingroup FileSystem\n");
|
"@ingroup FileSystem\n");
|
||||||
|
|
@ -1590,11 +1585,9 @@ ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef ar
|
||||||
ICallMethod *com = dynamic_cast<ICallMethod *>(object);
|
ICallMethod *com = dynamic_cast<ICallMethod *>(object);
|
||||||
if(com)
|
if(com)
|
||||||
{
|
{
|
||||||
STR.pushFrame();
|
gCallStack.pushFrame(0);
|
||||||
CSTK.pushFrame();
|
|
||||||
com->callMethodArgList(argc, argv, false);
|
com->callMethodArgList(argc, argv, false);
|
||||||
STR.popFrame();
|
gCallStack.popFrame();
|
||||||
CSTK.popFrame();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2523,70 +2516,20 @@ DefineEngineFunction( logWarning, void, ( const char* message ),,
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
extern ConsoleValueStack CSTK;
|
ConsoleValueToStringArrayWrapper::ConsoleValueToStringArrayWrapper(int targc, ConsoleValue *targv)
|
||||||
|
|
||||||
ConsoleValueRef::ConsoleValueRef(const ConsoleValueRef &ref)
|
|
||||||
{
|
|
||||||
value = ref.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueRef& ConsoleValueRef::operator=(const ConsoleValueRef &newValue)
|
|
||||||
{
|
|
||||||
value = newValue.value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueRef& ConsoleValueRef::operator=(const char *newValue)
|
|
||||||
{
|
|
||||||
AssertFatal(value, "value should not be NULL");
|
|
||||||
value->setStringValue(newValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueRef& ConsoleValueRef::operator=(S32 newValue)
|
|
||||||
{
|
|
||||||
AssertFatal(value, "value should not be NULL");
|
|
||||||
value->setIntValue(newValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueRef& ConsoleValueRef::operator=(U32 newValue)
|
|
||||||
{
|
|
||||||
AssertFatal(value, "value should not be NULL");
|
|
||||||
value->setIntValue(newValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueRef& ConsoleValueRef::operator=(F32 newValue)
|
|
||||||
{
|
|
||||||
AssertFatal(value, "value should not be NULL");
|
|
||||||
value->setFloatValue(newValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueRef& ConsoleValueRef::operator=(F64 newValue)
|
|
||||||
{
|
|
||||||
AssertFatal(value, "value should not be NULL");
|
|
||||||
value->setFloatValue(newValue);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
StringStackWrapper::StringStackWrapper(int targc, ConsoleValueRef targv[])
|
|
||||||
{
|
{
|
||||||
argv = new const char*[targc];
|
argv = new const char*[targc];
|
||||||
argc = targc;
|
argc = targc;
|
||||||
|
|
||||||
for (int i=0; i<targc; i++)
|
for (S32 i = 0; i < targc; i++)
|
||||||
{
|
{
|
||||||
argv[i] = dStrdup(targv[i]);
|
argv[i] = dStrdup(targv[i].getString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringStackWrapper::~StringStackWrapper()
|
ConsoleValueToStringArrayWrapper::~ConsoleValueToStringArrayWrapper()
|
||||||
{
|
{
|
||||||
for (int i=0; i<argc; i++)
|
for (S32 i = 0; i< argc; i++)
|
||||||
{
|
{
|
||||||
dFree(argv[i]);
|
dFree(argv[i]);
|
||||||
}
|
}
|
||||||
|
|
@ -2594,164 +2537,20 @@ StringStackWrapper::~StringStackWrapper()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StringStackConsoleWrapper::StringStackConsoleWrapper(int targc, const char** targ)
|
StringArrayToConsoleValueWrapper::StringArrayToConsoleValueWrapper(int targc, const char** targv)
|
||||||
{
|
{
|
||||||
argv = new ConsoleValueRef[targc];
|
argv = new ConsoleValue[targc];
|
||||||
argvValue = new ConsoleValue[targc];
|
|
||||||
argc = targc;
|
argc = targc;
|
||||||
|
|
||||||
for (int i=0; i<targc; i++) {
|
for (int i=0; i<targc; i++)
|
||||||
argvValue[i].init();
|
{
|
||||||
argv[i].value = &argvValue[i];
|
argv[i].setString(targv[i], dStrlen(targv[i]));
|
||||||
argvValue[i].setStackStringValue(targ[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringStackConsoleWrapper::~StringStackConsoleWrapper()
|
StringArrayToConsoleValueWrapper::~StringArrayToConsoleValueWrapper()
|
||||||
{
|
{
|
||||||
for (int i=0; i<argc; i++)
|
|
||||||
{
|
|
||||||
argv[i] = 0;
|
|
||||||
}
|
|
||||||
delete[] argv;
|
delete[] argv;
|
||||||
delete[] argvValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
S32 ConsoleValue::getSignedIntValue()
|
|
||||||
{
|
|
||||||
if(type <= TypeInternalString)
|
|
||||||
return (S32)fval;
|
|
||||||
else
|
|
||||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 ConsoleValue::getIntValue()
|
|
||||||
{
|
|
||||||
if(type <= TypeInternalString)
|
|
||||||
return ival;
|
|
||||||
else
|
|
||||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
|
||||||
}
|
|
||||||
|
|
||||||
F32 ConsoleValue::getFloatValue()
|
|
||||||
{
|
|
||||||
if(type <= TypeInternalString)
|
|
||||||
return fval;
|
|
||||||
else
|
|
||||||
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ConsoleValue::getStringValue()
|
|
||||||
{
|
|
||||||
if(type == TypeInternalString || type == TypeInternalStackString)
|
|
||||||
return sval;
|
|
||||||
else if (type == TypeInternalStringStackPtr)
|
|
||||||
return STR.mBuffer + (uintptr_t)sval;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We need a string representation, so lets create one
|
|
||||||
const char *internalValue = NULL;
|
|
||||||
|
|
||||||
if(type == TypeInternalFloat)
|
|
||||||
internalValue = Con::getData(TypeF32, &fval, 0);
|
|
||||||
else if(type == TypeInternalInt)
|
|
||||||
internalValue = Con::getData(TypeS32, &ival, 0);
|
|
||||||
else
|
|
||||||
return Con::getData(type, dataPtr, 0, enumTable); // We can't save sval here since it is the same as dataPtr
|
|
||||||
|
|
||||||
if (!internalValue)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
U32 stringLen = dStrlen(internalValue);
|
|
||||||
U32 newLen = ((stringLen + 1) + 15) & ~15; // pad upto next cache line
|
|
||||||
|
|
||||||
if (bufferLen == 0)
|
|
||||||
sval = (char *) dMalloc(newLen);
|
|
||||||
else if(newLen > bufferLen)
|
|
||||||
sval = (char *) dRealloc(sval, newLen);
|
|
||||||
|
|
||||||
dStrcpy(sval, internalValue, newLen);
|
|
||||||
bufferLen = newLen;
|
|
||||||
|
|
||||||
return sval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringStackPtr ConsoleValue::getStringStackPtr()
|
|
||||||
{
|
|
||||||
if (type == TypeInternalStringStackPtr)
|
|
||||||
return (uintptr_t)sval;
|
|
||||||
else
|
|
||||||
return (uintptr_t)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConsoleValue::getBoolValue()
|
|
||||||
{
|
|
||||||
if(type == TypeInternalString || type == TypeInternalStackString || type == TypeInternalStringStackPtr)
|
|
||||||
return dAtob(getStringValue());
|
|
||||||
if(type == TypeInternalFloat)
|
|
||||||
return fval > 0;
|
|
||||||
else if(type == TypeInternalInt)
|
|
||||||
return ival > 0;
|
|
||||||
else {
|
|
||||||
const char *value = Con::getData(type, dataPtr, 0, enumTable);
|
|
||||||
return dAtob(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleValue::setIntValue(S32 val)
|
|
||||||
{
|
|
||||||
setFloatValue(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleValue::setIntValue(U32 val)
|
|
||||||
{
|
|
||||||
if(type <= TypeInternalString)
|
|
||||||
{
|
|
||||||
fval = (F32)val;
|
|
||||||
ival = val;
|
|
||||||
if(bufferLen > 0)
|
|
||||||
{
|
|
||||||
dFree(sval);
|
|
||||||
bufferLen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sval = typeValueEmpty;
|
|
||||||
type = TypeInternalInt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *dptr = Con::getData(TypeS32, &val, 0);
|
|
||||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleValue::setBoolValue(bool val)
|
|
||||||
{
|
|
||||||
return setIntValue(val ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleValue::setFloatValue(F32 val)
|
|
||||||
{
|
|
||||||
if(type <= TypeInternalString)
|
|
||||||
{
|
|
||||||
fval = val;
|
|
||||||
ival = static_cast<U32>(val);
|
|
||||||
if(bufferLen > 0)
|
|
||||||
{
|
|
||||||
dFree(sval);
|
|
||||||
bufferLen = 0;
|
|
||||||
}
|
|
||||||
sval = typeValueEmpty;
|
|
||||||
type = TypeInternalFloat;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *dptr = Con::getData(TypeF32, &val, 0);
|
|
||||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -183,13 +183,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)->value.type)
|
switch ((*s)->value.getType())
|
||||||
{
|
{
|
||||||
case ConsoleValue::TypeInternalInt:
|
case ConsoleValueType::cvInteger:
|
||||||
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.ival, cat);
|
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.getInt(), cat);
|
||||||
break;
|
break;
|
||||||
case ConsoleValue::TypeInternalFloat:
|
case ConsoleValueType::cvFloat:
|
||||||
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.fval, cat);
|
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.getFloat(), cat);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
expandEscape(expandBuffer, (*s)->getStringValue());
|
expandEscape(expandBuffer, (*s)->getStringValue());
|
||||||
|
|
@ -243,13 +243,11 @@ void Dictionary::exportVariables(const char *varString, Vector<String> *names, V
|
||||||
|
|
||||||
if (values)
|
if (values)
|
||||||
{
|
{
|
||||||
switch ((*s)->value.type)
|
switch ((*s)->value.getType())
|
||||||
{
|
{
|
||||||
case ConsoleValue::TypeInternalInt:
|
case ConsoleValueType::cvInteger:
|
||||||
values->push_back(String::ToString((*s)->value.ival));
|
case ConsoleValueType::cvFloat:
|
||||||
break;
|
values->push_back(String((*s)->value.getString()));
|
||||||
case ConsoleValue::TypeInternalFloat:
|
|
||||||
values->push_back(String::ToString((*s)->value.fval));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
expandEscape(expandBuffer, (*s)->getStringValue());
|
expandEscape(expandBuffer, (*s)->getStringValue());
|
||||||
|
|
@ -470,7 +468,6 @@ char *typeValueEmpty = "";
|
||||||
Dictionary::Entry::Entry(StringTableEntry in_name)
|
Dictionary::Entry::Entry(StringTableEntry in_name)
|
||||||
{
|
{
|
||||||
name = in_name;
|
name = in_name;
|
||||||
value.type = ConsoleValue::TypeInternalString;
|
|
||||||
notify = NULL;
|
notify = NULL;
|
||||||
nextEntry = NULL;
|
nextEntry = NULL;
|
||||||
mUsage = NULL;
|
mUsage = NULL;
|
||||||
|
|
@ -508,150 +505,6 @@ const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleValue::setStringValue(const char * value)
|
|
||||||
{
|
|
||||||
if (value == NULL) value = typeValueEmpty;
|
|
||||||
|
|
||||||
if (type <= ConsoleValue::TypeInternalString)
|
|
||||||
{
|
|
||||||
// Let's not remove empty-string-valued global vars from the dict.
|
|
||||||
// If we remove them, then they won't be exported, and sometimes
|
|
||||||
// it could be necessary to export such a global. There are very
|
|
||||||
// few empty-string global vars so there's no performance-related
|
|
||||||
// need to remove them from the dict.
|
|
||||||
/*
|
|
||||||
if(!value[0] && name[0] == '$')
|
|
||||||
{
|
|
||||||
gEvalState.globalVars.remove(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (value == typeValueEmpty)
|
|
||||||
{
|
|
||||||
if (bufferLen > 0)
|
|
||||||
{
|
|
||||||
dFree(sval);
|
|
||||||
bufferLen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sval = typeValueEmpty;
|
|
||||||
fval = 0.f;
|
|
||||||
ival = 0;
|
|
||||||
type = TypeInternalString;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 stringLen = dStrlen(value);
|
|
||||||
|
|
||||||
// If it's longer than 256 bytes, it's certainly not a number.
|
|
||||||
//
|
|
||||||
// (This decision may come back to haunt you. Shame on you if it
|
|
||||||
// does.)
|
|
||||||
if (stringLen < 256)
|
|
||||||
{
|
|
||||||
fval = dAtof(value);
|
|
||||||
ival = dAtoi(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fval = 0.f;
|
|
||||||
ival = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// may as well pad to the next cache line
|
|
||||||
U32 newLen = ((stringLen + 1) + 15) & ~15;
|
|
||||||
|
|
||||||
if (bufferLen == 0)
|
|
||||||
sval = (char *)dMalloc(newLen);
|
|
||||||
else if (newLen > bufferLen)
|
|
||||||
sval = (char *)dRealloc(sval, newLen);
|
|
||||||
|
|
||||||
type = TypeInternalString;
|
|
||||||
|
|
||||||
bufferLen = newLen;
|
|
||||||
dStrcpy(sval, value, newLen);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ConsoleValue::setStackStringValue(const char *value)
|
|
||||||
{
|
|
||||||
if (value == NULL) value = typeValueEmpty;
|
|
||||||
|
|
||||||
if (type <= ConsoleValue::TypeInternalString)
|
|
||||||
{
|
|
||||||
// sval might still be temporarily present so we need to check and free it
|
|
||||||
if (bufferLen > 0)
|
|
||||||
{
|
|
||||||
dFree(sval);
|
|
||||||
bufferLen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == typeValueEmpty)
|
|
||||||
{
|
|
||||||
sval = typeValueEmpty;
|
|
||||||
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 = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
|
|
||||||
{
|
|
||||||
if (type <= ConsoleValue::TypeInternalString)
|
|
||||||
{
|
|
||||||
const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
|
|
||||||
if (bufferLen > 0)
|
|
||||||
{
|
|
||||||
dFree(sval);
|
|
||||||
bufferLen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 stringLen = dStrlen(value);
|
|
||||||
if (stringLen < 256)
|
|
||||||
{
|
|
||||||
fval = dAtof(value);
|
|
||||||
ival = dAtoi(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fval = 0.f;
|
|
||||||
ival = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = TypeInternalStringStackPtr;
|
|
||||||
sval = (char*)(value - STR.mBuffer);
|
|
||||||
bufferLen = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
|
|
||||||
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid)
|
S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid)
|
||||||
{
|
{
|
||||||
Entry *ent = lookup(name);
|
Entry *ent = lookup(name);
|
||||||
|
|
|
||||||
|
|
@ -324,17 +324,17 @@ public:
|
||||||
|
|
||||||
inline U32 getIntValue()
|
inline U32 getIntValue()
|
||||||
{
|
{
|
||||||
return value.getIntValue();
|
return value.getInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline F32 getFloatValue()
|
inline F32 getFloatValue()
|
||||||
{
|
{
|
||||||
return value.getFloatValue();
|
return value.getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *getStringValue()
|
inline const char *getStringValue()
|
||||||
{
|
{
|
||||||
return value.getStringValue();
|
return value.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIntValue(U32 val)
|
void setIntValue(U32 val)
|
||||||
|
|
@ -345,7 +345,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.setIntValue(val);
|
value.setInt(val);
|
||||||
|
|
||||||
// Fire off the notification if we have one.
|
// Fire off the notification if we have one.
|
||||||
if (notify)
|
if (notify)
|
||||||
|
|
@ -360,23 +360,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.setFloatValue(val);
|
value.setFloat(val);
|
||||||
|
|
||||||
// Fire off the notification if we have one.
|
|
||||||
if (notify)
|
|
||||||
notify->trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStringStackPtrValue(StringStackPtr newValue)
|
|
||||||
{
|
|
||||||
if (mIsConstant)
|
|
||||||
{
|
|
||||||
Con::errorf("Cannot assign value to constant '%s'.", name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
value.setStringStackPtrValue(newValue);
|
|
||||||
|
|
||||||
|
|
||||||
// Fire off the notification if we have one.
|
// Fire off the notification if we have one.
|
||||||
if (notify)
|
if (notify)
|
||||||
|
|
@ -391,8 +375,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.setStringValue(newValue);
|
value.setString(newValue, dStrlen(newValue));
|
||||||
|
|
||||||
|
|
||||||
// Fire off the notification if we have one.
|
// Fire off the notification if we have one.
|
||||||
if (notify)
|
if (notify)
|
||||||
|
|
@ -471,6 +454,18 @@ public:
|
||||||
void validate();
|
void validate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ConsoleValueFrame
|
||||||
|
{
|
||||||
|
ConsoleValue* values;
|
||||||
|
bool isReference;
|
||||||
|
|
||||||
|
ConsoleValueFrame(ConsoleValue* vals, bool isRef)
|
||||||
|
{
|
||||||
|
values = vals;
|
||||||
|
isReference = isRef;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ExprEvalState
|
class ExprEvalState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -499,6 +494,9 @@ public:
|
||||||
/// an interior pointer that will become invalid when the object changes address.
|
/// an interior pointer that will become invalid when the object changes address.
|
||||||
Vector< Dictionary* > stack;
|
Vector< Dictionary* > stack;
|
||||||
|
|
||||||
|
Vector< ConsoleValueFrame > localStack;
|
||||||
|
ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack
|
||||||
|
|
||||||
///
|
///
|
||||||
Dictionary globalVars;
|
Dictionary globalVars;
|
||||||
|
|
||||||
|
|
@ -511,10 +509,43 @@ public:
|
||||||
void setIntVariable(S32 val);
|
void setIntVariable(S32 val);
|
||||||
void setFloatVariable(F64 val);
|
void setFloatVariable(F64 val);
|
||||||
void setStringVariable(const char *str);
|
void setStringVariable(const char *str);
|
||||||
void setStringStackPtrVariable(StringStackPtr str);
|
|
||||||
void setCopyVariable();
|
|
||||||
|
|
||||||
void pushFrame(StringTableEntry frameName, Namespace *ns);
|
TORQUE_FORCEINLINE S32 getLocalIntVariable(S32 reg)
|
||||||
|
{
|
||||||
|
return currentRegisterArray->values[reg].getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE F64 getLocalFloatVariable(S32 reg)
|
||||||
|
{
|
||||||
|
return currentRegisterArray->values[reg].getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE const char* getLocalStringVariable(S32 reg)
|
||||||
|
{
|
||||||
|
return currentRegisterArray->values[reg].getString();
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void setLocalIntVariable(S32 reg, S64 val)
|
||||||
|
{
|
||||||
|
currentRegisterArray->values[reg].setInt(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void setLocalFloatVariable(S32 reg, F64 val)
|
||||||
|
{
|
||||||
|
currentRegisterArray->values[reg].setFloat(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void setLocalStringVariable(S32 reg, const char* val, S32 len)
|
||||||
|
{
|
||||||
|
currentRegisterArray->values[reg].setString(val, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void setLocalStringTableEntryVariable(S32 reg, StringTableEntry val)
|
||||||
|
{
|
||||||
|
currentRegisterArray->values[reg].setStringTableEntry(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushFrame(StringTableEntry frameName, Namespace *ns, S32 regCount);
|
||||||
void popFrame();
|
void popFrame();
|
||||||
|
|
||||||
/// Puts a reference to an existing stack frame
|
/// Puts a reference to an existing stack frame
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ void ConsoleLogger::initPersistFields()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ConsoleLogger::processArguments( S32 argc, ConsoleValueRef *argv )
|
bool ConsoleLogger::processArguments( S32 argc, ConsoleValue *argv )
|
||||||
{
|
{
|
||||||
if( argc == 0 )
|
if( argc == 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -87,10 +87,10 @@ bool ConsoleLogger::processArguments( S32 argc, ConsoleValueRef *argv )
|
||||||
bool append = false;
|
bool append = false;
|
||||||
|
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
append = dAtob( argv[1] );
|
append = argv[1].getBool();
|
||||||
|
|
||||||
mAppend = append;
|
mAppend = append;
|
||||||
mFilename = StringTable->insert( argv[0] );
|
mFilename = StringTable->insert( argv[0].getString() );
|
||||||
|
|
||||||
if( init() )
|
if( init() )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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, ConsoleValueRef *argv );
|
bool processArguments( S32 argc, ConsoleValue *argv );
|
||||||
|
|
||||||
/// Default constructor, make sure to initalize
|
/// Default constructor, make sure to initalize
|
||||||
ConsoleLogger();
|
ConsoleLogger();
|
||||||
|
|
|
||||||
121
Engine/source/console/consoleValueStack.h
Normal file
121
Engine/source/console/consoleValueStack.h
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2013 GarageGames, LLC
|
||||||
|
// Copyright (c) 2021 TGEMIT Authors & Contributors
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to
|
||||||
|
// deal in the Software without restriction, including without limitation the
|
||||||
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
// sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
// IN THE SOFTWARE.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef _CONSOLE_CONSOLE_VALUE_STACK_H_
|
||||||
|
#define _CONSOLE_CONSOLE_VALUE_STACK_H_
|
||||||
|
|
||||||
|
template<S32 StackSize>
|
||||||
|
class ConsoleValueStack
|
||||||
|
{
|
||||||
|
constexpr static S32 allocatorSize = sizeof(ConsoleValue) * StackSize;
|
||||||
|
|
||||||
|
struct Frame
|
||||||
|
{
|
||||||
|
ConsoleValue* values;
|
||||||
|
S32 count;
|
||||||
|
S32 internalCounter;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<Frame> stack;
|
||||||
|
char* memory;
|
||||||
|
S32 sp;
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE Frame alloc(S32 count)
|
||||||
|
{
|
||||||
|
AssertFatal(sp + count * sizeof(ConsoleValue) < allocatorSize, "ConsoleValueStack overflow");
|
||||||
|
|
||||||
|
ConsoleValue* ret = reinterpret_cast<ConsoleValue*>(memory + sp);
|
||||||
|
sp += count * sizeof(ConsoleValue);
|
||||||
|
|
||||||
|
return { ret, count, 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void deAlloc(S32 count)
|
||||||
|
{
|
||||||
|
sp -= count * sizeof(ConsoleValue);
|
||||||
|
AssertFatal(sp >= 0, "Popped ConsoleValueStack too far, underflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConsoleValueStack()
|
||||||
|
{
|
||||||
|
memory = (char*)dMalloc(allocatorSize);
|
||||||
|
for (S32 i = 0; i < allocatorSize; i += sizeof(ConsoleValue))
|
||||||
|
{
|
||||||
|
constructInPlace<ConsoleValue>(reinterpret_cast<ConsoleValue*>(memory + i));
|
||||||
|
}
|
||||||
|
sp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ConsoleValueStack()
|
||||||
|
{
|
||||||
|
dFree(memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void pushFrame(S32 count)
|
||||||
|
{
|
||||||
|
AssertISV(count >= 0, "Must be >= 0 when pushing stack frame");
|
||||||
|
|
||||||
|
// +1 for function name in argv[0]
|
||||||
|
const Frame& frame = alloc(count + 1);
|
||||||
|
stack.push_back(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void popFrame()
|
||||||
|
{
|
||||||
|
AssertISV(stack.size() > 0, "Stack Underflow");
|
||||||
|
|
||||||
|
deAlloc(stack.last().count);
|
||||||
|
stack.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void pushInt(S64 value)
|
||||||
|
{
|
||||||
|
Frame& frame = stack.last();
|
||||||
|
frame.values[frame.internalCounter++].setInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void pushFloat(F64 value)
|
||||||
|
{
|
||||||
|
Frame& frame = stack.last();
|
||||||
|
frame.values[frame.internalCounter++].setFloat(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void pushString(const char* value, S32 len)
|
||||||
|
{
|
||||||
|
Frame& frame = stack.last();
|
||||||
|
frame.values[frame.internalCounter++].setString(value, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void argvc(StringTableEntry fn, S32& argc, ConsoleValue** argv)
|
||||||
|
{
|
||||||
|
Frame& frame = stack.last();
|
||||||
|
argc = frame.count;
|
||||||
|
|
||||||
|
// First param is always function name
|
||||||
|
frame.values[0].setStringTableEntry(fn);
|
||||||
|
*argv = frame.values;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -125,15 +125,12 @@ namespace Sim
|
||||||
SimDataBlockGroup *getDataBlockGroup();
|
SimDataBlockGroup *getDataBlockGroup();
|
||||||
SimGroup* getRootGroup();
|
SimGroup* getRootGroup();
|
||||||
|
|
||||||
SimObject* findObject(ConsoleValueRef&);
|
|
||||||
SimObject* findObject(SimObjectId);
|
SimObject* findObject(SimObjectId);
|
||||||
|
SimObject* findObject(const ConsoleValue&);
|
||||||
|
SimObject* findObject(ConsoleValue*);
|
||||||
SimObject* findObject(const char* name);
|
SimObject* findObject(const char* name);
|
||||||
SimObject* findObject(const char* fileName, S32 declarationLine);
|
SimObject* findObject(const char* fileName, S32 declarationLine);
|
||||||
template<class T> inline bool findObject(ConsoleValueRef &ref,T*&t)
|
|
||||||
{
|
|
||||||
t = dynamic_cast<T*>(findObject(ref));
|
|
||||||
return t != NULL;
|
|
||||||
}
|
|
||||||
template<class T> inline bool findObject(SimObjectId iD,T*&t)
|
template<class T> inline bool findObject(SimObjectId iD,T*&t)
|
||||||
{
|
{
|
||||||
t = dynamic_cast<T*>(findObject(iD));
|
t = dynamic_cast<T*>(findObject(iD));
|
||||||
|
|
|
||||||
|
|
@ -328,11 +328,6 @@ SimObject* findObject(const char* fileName, S32 declarationLine)
|
||||||
return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true);
|
return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimObject* findObject(ConsoleValueRef &ref)
|
|
||||||
{
|
|
||||||
return findObject((const char*)ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
SimObject* findObject(const char* name)
|
SimObject* findObject(const char* name)
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(SimFindObject);
|
PROFILE_SCOPE(SimFindObject);
|
||||||
|
|
@ -391,6 +386,24 @@ SimObject* findObject(const char* name)
|
||||||
return obj->findObject(name + len + 1);
|
return obj->findObject(name + len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SimObject* findObject(const ConsoleValue &val)
|
||||||
|
{
|
||||||
|
if (val.getType() == ConsoleValueType::cvNone)
|
||||||
|
return NULL;
|
||||||
|
if (val.getType() == ConsoleValueType::cvInteger)
|
||||||
|
return findObject((SimObjectId)val.getInt());
|
||||||
|
return findObject(val.getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
SimObject* findObject(ConsoleValue* val)
|
||||||
|
{
|
||||||
|
if (val->getType() == ConsoleValueType::cvNone)
|
||||||
|
return NULL;
|
||||||
|
if (val->getType() == ConsoleValueType::cvInteger)
|
||||||
|
return findObject((SimObjectId)val->getInt());
|
||||||
|
return findObject(val->getString());
|
||||||
|
}
|
||||||
|
|
||||||
SimObject* findObject(SimObjectId id)
|
SimObject* findObject(SimObjectId id)
|
||||||
{
|
{
|
||||||
return gIdDictionary->find(id);
|
return gIdDictionary->find(id);
|
||||||
|
|
|
||||||
|
|
@ -229,11 +229,16 @@ void SimSet::scriptSort( const String &scriptCallbackFn )
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups )
|
void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValue argv[], bool executeOnChildGroups )
|
||||||
{
|
{
|
||||||
|
// TODO(JTH): Implement
|
||||||
|
AssertISV(false, "TODO Implement");
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
// 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.
|
||||||
ConsoleValueRef args[21] = { };
|
ConsoleValue args[21] = { };
|
||||||
ConsoleValue name_method;
|
ConsoleValue name_method;
|
||||||
name_method.setStackStringValue(method.c_str());
|
name_method.setStackStringValue(method.c_str());
|
||||||
args[0] = ConsoleValueRef::fromValue(&name_method);
|
args[0] = ConsoleValueRef::fromValue(&name_method);
|
||||||
|
|
@ -255,6 +260,7 @@ void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef arg
|
||||||
childSet->callOnChildren( method, argc, argv, executeOnChildGroups );
|
childSet->callOnChildren( method, argc, argv, executeOnChildGroups );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -838,7 +844,7 @@ SimGroup* SimGroup::deepClone()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool SimGroup::processArguments(S32, ConsoleValueRef *argv)
|
bool SimGroup::processArguments(S32, ConsoleValue *argv)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ class SimSet : public SimObject, public TamlChildren
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
void callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups = true );
|
void callOnChildren( const String &method, S32 argc, ConsoleValue 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.
|
||||||
|
|
@ -464,7 +464,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, ConsoleValueRef *argv );
|
virtual bool processArguments( S32 argc, ConsoleValue *argv );
|
||||||
|
|
||||||
virtual SimObject* getObject(const S32& index);
|
virtual SimObject* getObject(const S32& index);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -207,228 +207,3 @@ void StringStack::clearFrames()
|
||||||
mStartStackSize = 0;
|
mStartStackSize = 0;
|
||||||
mFunctionOffset = 0;
|
mFunctionOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame /* = false */)
|
|
||||||
{
|
|
||||||
U32 startStack = mStackFrames[mFrame-1];
|
|
||||||
U32 argCount = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
|
|
||||||
|
|
||||||
*in_argv = mArgv;
|
|
||||||
mArgv[0].value = CSTK.pushStackString(name);
|
|
||||||
|
|
||||||
for(U32 i = 0; i < argCount; i++) {
|
|
||||||
ConsoleValueRef *ref = &mArgv[i+1];
|
|
||||||
ref->value = &mStack[startStack + i];
|
|
||||||
}
|
|
||||||
argCount++;
|
|
||||||
|
|
||||||
*argc = argCount;
|
|
||||||
|
|
||||||
if(popStackFrame)
|
|
||||||
popFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValueStack::ConsoleValueStack() :
|
|
||||||
mFrame(0),
|
|
||||||
mStackPos(0)
|
|
||||||
{
|
|
||||||
for (int i=0; i<ConsoleValueStack::MaxStackDepth; i++) {
|
|
||||||
mStack[i].init();
|
|
||||||
mStack[i].type = ConsoleValue::TypeInternalString;
|
|
||||||
}
|
|
||||||
dMemset(mStackFrames, 0, sizeof(mStackFrames));
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
case ConsoleValue::TypeInternalStringStackPtr:
|
|
||||||
mStack[mStackPos++].setStringStackPtrValue(variable.getStringStackPtr());
|
|
||||||
default:
|
|
||||||
mStack[mStackPos++].setStringValue(variable.getStringValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleValue* ConsoleValueStack::reserveValues(U32 count)
|
|
||||||
{
|
|
||||||
U32 startPos = mStackPos;
|
|
||||||
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
|
|
||||||
AssertFatal(false, "Console Value Stack is empty");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
|
|
||||||
mStackPos += count;
|
|
||||||
return &mStack[startPos];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConsoleValueStack::reserveValues(U32 count, ConsoleValueRef *outValues)
|
|
||||||
{
|
|
||||||
U32 startPos = mStackPos;
|
|
||||||
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
|
|
||||||
AssertFatal(false, "Console Value Stack is empty");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
|
|
||||||
for (U32 i=0; i<count; i++)
|
|
||||||
{
|
|
||||||
outValues[i].value = &mStack[mStackPos+i];
|
|
||||||
}
|
|
||||||
mStackPos += count;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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::pushStringStackPtr(StringStackPtr value)
|
|
||||||
{
|
|
||||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
|
||||||
AssertFatal(false, "Console Value Stack is empty");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Con::printf("[%i]CSTK pushStringStackPtr %s", mStackPos, StringStackPtrRef(value).getPtr(&STR));
|
|
||||||
|
|
||||||
mStack[mStackPos++].setStringStackPtrValue(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[%i] (%i)", mFrame, mStackPos);
|
|
||||||
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::clearFrames()
|
|
||||||
{
|
|
||||||
mStackPos = 0;
|
|
||||||
mFrame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -189,51 +189,7 @@ 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* reserveValues(U32 numValues);
|
|
||||||
bool reserveValues(U32 numValues, ConsoleValueRef *values);
|
|
||||||
ConsoleValue* pop();
|
|
||||||
|
|
||||||
ConsoleValue *pushString(const char *value);
|
|
||||||
ConsoleValue *pushStackString(const char *value);
|
|
||||||
ConsoleValue *pushStringStackPtr(StringStackPtr ptr);
|
|
||||||
ConsoleValue *pushUINT(U32 value);
|
|
||||||
ConsoleValue *pushFLT(float value);
|
|
||||||
|
|
||||||
void pushFrame();
|
|
||||||
void popFrame();
|
|
||||||
|
|
||||||
void resetFrame();
|
|
||||||
void clearFrames();
|
|
||||||
|
|
||||||
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];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern StringStack STR;
|
extern StringStack STR;
|
||||||
extern ConsoleValueStack CSTK;
|
|
||||||
|
|
||||||
inline char* StringStackPtrRef::getPtr(StringStack *stk) { return stk->mBuffer + mOffset; }
|
inline char* StringStackPtrRef::getPtr(StringStack *stk) { return stk->mBuffer + mOffset; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef 0
|
||||||
#ifdef TORQUE_TESTS_ENABLED
|
#ifdef TORQUE_TESTS_ENABLED
|
||||||
#include "testing/unitTesting.h"
|
#include "testing/unitTesting.h"
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
@ -393,3 +394,4 @@ TEST(Script, Basic_Package)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#ifdef 0
|
||||||
|
|
||||||
#ifdef TORQUE_TESTS_ENABLED
|
#ifdef TORQUE_TESTS_ENABLED
|
||||||
#include "testing/unitTesting.h"
|
#include "testing/unitTesting.h"
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
@ -253,3 +255,4 @@ TEST(Con, execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#if 0
|
||||||
#ifdef TORQUE_TESTS_ENABLED
|
#ifdef TORQUE_TESTS_ENABLED
|
||||||
#include "testing/unitTesting.h"
|
#include "testing/unitTesting.h"
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
@ -148,3 +149,4 @@ TEST(EngineAPI, _EngineConsoleExecCallbackHelper)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,11 @@ inline F64 dAtod(const char *str)
|
||||||
return strtod(str, NULL);
|
return strtod(str, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline S64 dAtol(const char* str)
|
||||||
|
{
|
||||||
|
return strtol(str, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
inline char dToupper(const char c)
|
inline char dToupper(const char c)
|
||||||
{
|
{
|
||||||
return toupper( c );
|
return toupper( c );
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ void WaterObject::inspectPostApply()
|
||||||
setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask );
|
setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaterObject::processArguments( S32 argc, ConsoleValueRef *argv )
|
bool WaterObject::processArguments( S32 argc, ConsoleValue *argv )
|
||||||
{
|
{
|
||||||
if( typeid( *this ) == typeid( WaterObject ) )
|
if( typeid( *this ) == typeid( WaterObject ) )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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, ConsoleValueRef *argv);
|
virtual bool processArguments(S32 argc, ConsoleValue *argv);
|
||||||
|
|
||||||
// NetObject
|
// NetObject
|
||||||
virtual U32 packUpdate( NetConnection * conn, U32 mask, BitStream *stream );
|
virtual U32 packUpdate( NetConnection * conn, U32 mask, BitStream *stream );
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,7 @@ void GuiControl::initPersistFields()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool GuiControl::processArguments(S32 argc, ConsoleValueRef *argv)
|
bool GuiControl::processArguments(S32 argc, ConsoleValue *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
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ class GuiControl : public SimGroup
|
||||||
|
|
||||||
GuiControl();
|
GuiControl();
|
||||||
virtual ~GuiControl();
|
virtual ~GuiControl();
|
||||||
virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
|
virtual bool processArguments(S32 argc, ConsoleValue *argv);
|
||||||
|
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
static void consoleInit();
|
static void consoleInit();
|
||||||
|
|
|
||||||
|
|
@ -2858,17 +2858,17 @@ void WorldEditor::initPersistFields()
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// These methods are needed for the console interfaces.
|
// These methods are needed for the console interfaces.
|
||||||
|
|
||||||
void WorldEditor::ignoreObjClass( U32 argc, ConsoleValueRef *argv )
|
void WorldEditor::ignoreObjClass( U32 argc, ConsoleValue *argv )
|
||||||
{
|
{
|
||||||
for(S32 i = 2; i < argc; i++)
|
for(S32 i = 2; i < argc; i++)
|
||||||
{
|
{
|
||||||
ClassInfo::Entry * entry = getClassEntry(argv[i]);
|
ClassInfo::Entry * entry = getClassEntry(argv[i].getString());
|
||||||
if(entry)
|
if(entry)
|
||||||
entry->mIgnoreCollision = true;
|
entry->mIgnoreCollision = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
entry = new ClassInfo::Entry;
|
entry = new ClassInfo::Entry;
|
||||||
entry->mName = StringTable->insert(argv[i]);
|
entry->mName = StringTable->insert(argv[i].getString());
|
||||||
entry->mIgnoreCollision = true;
|
entry->mIgnoreCollision = true;
|
||||||
if(!addClassEntry(entry))
|
if(!addClassEntry(entry))
|
||||||
delete entry;
|
delete entry;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class WorldEditor : public EditTSCtrl
|
||||||
Point3F p2;
|
Point3F p2;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ignoreObjClass(U32 argc, ConsoleValueRef* argv);
|
void ignoreObjClass(U32 argc, ConsoleValue* 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; };
|
||||||
|
|
|
||||||
|
|
@ -55,31 +55,36 @@ DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
|
||||||
}
|
}
|
||||||
for (argc--, argv++; argc; argc--, argv++)
|
for (argc--, argv++; argc; argc--, argv++)
|
||||||
{
|
{
|
||||||
if (dStricmp(*argv, "DETECT") == 0) {
|
const char* str = (*argv).getString();
|
||||||
|
if (dStricmp(str, "DETECT") == 0) {
|
||||||
Math::init(0);
|
Math::init(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dStricmp(*argv, "C") == 0) {
|
if (dStricmp(str, "C") == 0) {
|
||||||
properties |= CPU_PROP_C;
|
properties |= CPU_PROP_C;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dStricmp(*argv, "FPU") == 0) {
|
if (dStricmp(str, "FPU") == 0) {
|
||||||
properties |= CPU_PROP_FPU;
|
properties |= CPU_PROP_FPU;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dStricmp(*argv, "MMX") == 0) {
|
if (dStricmp(str, "MMX") == 0) {
|
||||||
properties |= CPU_PROP_MMX;
|
properties |= CPU_PROP_MMX;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dStricmp(*argv, "3DNOW") == 0) {
|
if (dStricmp(str, "3DNOW") == 0) {
|
||||||
properties |= CPU_PROP_3DNOW;
|
properties |= CPU_PROP_3DNOW;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dStricmp(*argv, "SSE") == 0) {
|
if (dStricmp(str, "SSE") == 0) {
|
||||||
properties |= CPU_PROP_SSE;
|
properties |= CPU_PROP_SSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", argv->getStringValue());
|
if (dStricmp(str, "SSE2") == 0) {
|
||||||
|
properties |= CPU_PROP_SSE2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", str);
|
||||||
}
|
}
|
||||||
Math::init(properties);
|
Math::init(properties);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ void SFXSource::initPersistFields()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool SFXSource::processArguments( S32 argc, ConsoleValueRef *argv )
|
bool SFXSource::processArguments( S32 argc, ConsoleValue *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.
|
||||||
|
|
|
||||||
|
|
@ -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, ConsoleValueRef *argv );
|
virtual bool processArguments( S32 argc, ConsoleValue *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 );
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ void SFXTrack::initPersistFields()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool SFXTrack::processArguments( S32 argc, ConsoleValueRef *argv )
|
bool SFXTrack::processArguments( S32 argc, ConsoleValue *argv )
|
||||||
{
|
{
|
||||||
if( typeid( *this ) == typeid( SFXTrack ) )
|
if( typeid( *this ) == typeid( SFXTrack ) )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,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, ConsoleValueRef *argv );
|
virtual bool processArguments( S32 argc, ConsoleValue *argv );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ void CustomFeatureGLSL::addVertTexCoord(String name)
|
||||||
mVars.push_back(newVarHolder);
|
mVars.push_back(newVarHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv)
|
void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValue * argv)
|
||||||
{
|
{
|
||||||
//do the var/arg fetching here
|
//do the var/arg fetching here
|
||||||
Vector<Var*> varList;
|
Vector<Var*> varList;
|
||||||
|
|
@ -246,7 +246,7 @@ void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
|
||||||
|
|
||||||
for (U32 i = 0; i < argc; i++)
|
for (U32 i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
String varName = argv[i].getStringValue();
|
String varName = argv[i].getString();
|
||||||
Var* newVar = (Var*)LangElement::find(varName.c_str());
|
Var* newVar = (Var*)LangElement::find(varName.c_str());
|
||||||
if (!newVar)
|
if (!newVar)
|
||||||
{
|
{
|
||||||
|
|
@ -304,7 +304,7 @@ void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
|
||||||
if (!newVar)
|
if (!newVar)
|
||||||
{
|
{
|
||||||
//couldn't find that variable, bail out
|
//couldn't find that variable, bail out
|
||||||
Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue());
|
Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,5 +128,5 @@ public:
|
||||||
void addTexture(String name, String type, String samplerState, U32 arraySize);
|
void addTexture(String name, String type, String samplerState, U32 arraySize);
|
||||||
void addConnector(String name, String type, String elementName);
|
void addConnector(String name, String type, String elementName);
|
||||||
void addVertTexCoord(String name);
|
void addVertTexCoord(String name);
|
||||||
void writeLine(String format, S32 argc, ConsoleValueRef* argv);
|
void writeLine(String format, S32 argc, ConsoleValue* argv);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ void CustomFeatureHLSL::addVertTexCoord(String name)
|
||||||
mVars.push_back(newVarHolder);
|
mVars.push_back(newVarHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv)
|
void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValue *argv)
|
||||||
{
|
{
|
||||||
//do the var/arg fetching here
|
//do the var/arg fetching here
|
||||||
Vector<Var*> varList;
|
Vector<Var*> varList;
|
||||||
|
|
@ -393,7 +393,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
|
||||||
|
|
||||||
for (U32 i = 0; i < argc; i++)
|
for (U32 i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
String varName = argv[i].getStringValue();
|
String varName = argv[i].getString();
|
||||||
Var* newVar = (Var*)LangElement::find(varName.c_str());
|
Var* newVar = (Var*)LangElement::find(varName.c_str());
|
||||||
if (!newVar)
|
if (!newVar)
|
||||||
{
|
{
|
||||||
|
|
@ -451,7 +451,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
|
||||||
if (!newVar)
|
if (!newVar)
|
||||||
{
|
{
|
||||||
//couldn't find that variable, bail out
|
//couldn't find that variable, bail out
|
||||||
Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue());
|
Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,5 +128,5 @@ public:
|
||||||
void addTexture(String name, String type, String samplerState, U32 arraySize);
|
void addTexture(String name, String type, String samplerState, U32 arraySize);
|
||||||
void addConnector(String name, String type, String elementName);
|
void addConnector(String name, String type, String elementName);
|
||||||
void addVertTexCoord(String name);
|
void addVertTexCoord(String name);
|
||||||
void writeLine(String format, S32 argc, ConsoleValueRef* argv);
|
void writeLine(String format, S32 argc, ConsoleValue* argv);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ bool CustomShaderFeatureData::hasFeature(String name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValueRef* argv)
|
void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValue* argv)
|
||||||
{
|
{
|
||||||
#ifdef TORQUE_D3D11
|
#ifdef TORQUE_D3D11
|
||||||
if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
|
if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ public:
|
||||||
void addVertTexCoord(String name);
|
void addVertTexCoord(String name);
|
||||||
bool hasFeature(String name);
|
bool hasFeature(String name);
|
||||||
|
|
||||||
void writeLine(String format, S32 argc, ConsoleValueRef *argv);
|
void writeLine(String format, S32 argc, ConsoleValue *argv);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue