Merge pull request #13 from eightyeight/x64

jamesu's AST refactor
This commit is contained in:
LuisAntonRebollo 2014-09-26 00:06:01 +02:00
commit c633933554
9 changed files with 973 additions and 1039 deletions

View file

@ -27,6 +27,7 @@ class ExprEvalState;
class Namespace; class Namespace;
class SimObject; class SimObject;
class SimGroup; class SimGroup;
class CodeStream;
/// Enable this #define if you are seeing the message "precompile size mismatch" in the console. /// Enable this #define if you are seeing the message "precompile size mismatch" in the console.
/// This will help track down which node type is causing the error. It could be /// This will help track down which node type is causing the error. It could be
@ -77,15 +78,13 @@ struct StmtNode
/// @name Breaking /// @name Breaking
/// @{ /// @{
void addBreakCount(); void addBreakLine(CodeStream &codeStream);
void addBreakLine(U32 ip);
/// @} /// @}
/// @name Compilation /// @name Compilation
/// @{ /// @{
virtual U32 precompileStmt(U32 loopCount) = 0; virtual U32 compileStmt(CodeStream &codeStream, U32 ip) = 0;
virtual U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint) = 0;
virtual void setPackage(StringTableEntry packageName); virtual void setPackage(StringTableEntry packageName);
/// @} /// @}
}; };
@ -101,27 +100,26 @@ struct BreakStmtNode : StmtNode
{ {
static BreakStmtNode *alloc( S32 lineNumber ); static BreakStmtNode *alloc( S32 lineNumber );
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
DBG_STMT_TYPE(BreakStmtNode); DBG_STMT_TYPE(BreakStmtNode);
}; };
struct ContinueStmtNode : StmtNode struct ContinueStmtNode : StmtNode
{ {
static ContinueStmtNode *alloc( S32 lineNumber ); static ContinueStmtNode *alloc( S32 lineNumber );
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
DBG_STMT_TYPE(ContinueStmtNode); DBG_STMT_TYPE(ContinueStmtNode);
}; };
/// A mathematical expression. /// A mathematical expression.
struct ExprNode : StmtNode struct ExprNode : StmtNode
{ {
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
virtual U32 precompile(TypeReq type) = 0; virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type) = 0;
virtual U32 compile(U32 *codeStream, U32 ip, TypeReq type) = 0;
virtual TypeReq getPreferredType() = 0; virtual TypeReq getPreferredType() = 0;
}; };
@ -130,8 +128,8 @@ struct ReturnStmtNode : StmtNode
ExprNode *expr; ExprNode *expr;
static ReturnStmtNode *alloc( S32 lineNumber, ExprNode *expr ); static ReturnStmtNode *alloc( S32 lineNumber, ExprNode *expr );
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
DBG_STMT_TYPE(ReturnStmtNode); DBG_STMT_TYPE(ReturnStmtNode);
}; };
@ -147,8 +145,8 @@ struct IfStmtNode : StmtNode
static IfStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough ); static IfStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough );
void propagateSwitchExpr(ExprNode *left, bool string); void propagateSwitchExpr(ExprNode *left, bool string);
ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string); ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string);
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
DBG_STMT_TYPE(IfStmtNode); DBG_STMT_TYPE(IfStmtNode);
}; };
@ -165,8 +163,8 @@ struct LoopStmtNode : StmtNode
bool integer; bool integer;
static LoopStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop ); static LoopStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop );
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
DBG_STMT_TYPE(LoopStmtNode); DBG_STMT_TYPE(LoopStmtNode);
}; };
@ -190,8 +188,7 @@ struct IterStmtNode : StmtNode
static IterStmtNode* alloc( S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter ); static IterStmtNode* alloc( S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter );
U32 precompileStmt( U32 loopCount ); U32 compileStmt( CodeStream &codeStream, U32 ip );
U32 compileStmt( U32* codeStream, U32 ip, U32 continuePoint, U32 breakPoint );
}; };
/// A binary mathematical expression (ie, left op right). /// A binary mathematical expression (ie, left op right).
@ -205,8 +202,8 @@ struct BinaryExprNode : ExprNode
struct FloatBinaryExprNode : BinaryExprNode 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 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FloatBinaryExprNode); DBG_STMT_TYPE(FloatBinaryExprNode);
}; };
@ -218,8 +215,8 @@ struct ConditionalExprNode : ExprNode
ExprNode *falseExpr; ExprNode *falseExpr;
bool integer; bool integer;
static ConditionalExprNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr ); static ConditionalExprNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr );
virtual U32 precompile(TypeReq type);
virtual U32 compile(U32 *codeStream, U32 ip, TypeReq type); virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
virtual TypeReq getPreferredType(); virtual TypeReq getPreferredType();
DBG_STMT_TYPE(ConditionalExprNode); DBG_STMT_TYPE(ConditionalExprNode);
}; };
@ -232,8 +229,8 @@ struct IntBinaryExprNode : BinaryExprNode
static IntBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right ); static IntBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right );
void getSubTypeOperand(); void getSubTypeOperand();
U32 precompile(TypeReq type);
U32 compile(U32 *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);
}; };
@ -242,8 +239,8 @@ struct StreqExprNode : BinaryExprNode
{ {
bool eq; bool eq;
static StreqExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, bool eq ); static StreqExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, bool eq );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(StreqExprNode); DBG_STMT_TYPE(StreqExprNode);
}; };
@ -252,8 +249,8 @@ struct StrcatExprNode : BinaryExprNode
{ {
S32 appendChar; S32 appendChar;
static StrcatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar ); static StrcatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(StrcatExprNode); DBG_STMT_TYPE(StrcatExprNode);
}; };
@ -262,8 +259,8 @@ struct CommaCatExprNode : BinaryExprNode
{ {
static CommaCatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right ); static CommaCatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(CommaCatExprNode); DBG_STMT_TYPE(CommaCatExprNode);
}; };
@ -275,8 +272,8 @@ struct IntUnaryExprNode : ExprNode
bool integer; bool integer;
static IntUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr ); static IntUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(IntUnaryExprNode); DBG_STMT_TYPE(IntUnaryExprNode);
}; };
@ -287,8 +284,8 @@ struct FloatUnaryExprNode : ExprNode
ExprNode *expr; ExprNode *expr;
static FloatUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr ); static FloatUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FloatUnaryExprNode); DBG_STMT_TYPE(FloatUnaryExprNode);
}; };
@ -299,8 +296,8 @@ struct VarNode : ExprNode
ExprNode *arrayIndex; ExprNode *arrayIndex;
static VarNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex ); static VarNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(VarNode); DBG_STMT_TYPE(VarNode);
}; };
@ -311,8 +308,8 @@ struct IntNode : ExprNode
U32 index; // if it's converted to float/string U32 index; // if it's converted to float/string
static IntNode *alloc( S32 lineNumber, S32 value ); static IntNode *alloc( S32 lineNumber, S32 value );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(IntNode); DBG_STMT_TYPE(IntNode);
}; };
@ -323,8 +320,8 @@ struct FloatNode : ExprNode
U32 index; U32 index;
static FloatNode *alloc( S32 lineNumber, F64 value ); static FloatNode *alloc( S32 lineNumber, F64 value );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FloatNode); DBG_STMT_TYPE(FloatNode);
}; };
@ -338,8 +335,8 @@ struct StrConstNode : ExprNode
bool doc; // Specifies that this string is a documentation block. bool doc; // Specifies that this string is a documentation block.
static StrConstNode *alloc( S32 lineNumber, char *str, bool tag, bool doc = false ); static StrConstNode *alloc( S32 lineNumber, char *str, bool tag, bool doc = false );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(StrConstNode); DBG_STMT_TYPE(StrConstNode);
}; };
@ -351,8 +348,8 @@ struct ConstantNode : ExprNode
U32 index; U32 index;
static ConstantNode *alloc( S32 lineNumber, StringTableEntry value ); static ConstantNode *alloc( S32 lineNumber, StringTableEntry value );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(ConstantNode); DBG_STMT_TYPE(ConstantNode);
}; };
@ -365,8 +362,8 @@ struct AssignExprNode : ExprNode
TypeReq subType; TypeReq subType;
static AssignExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr ); static AssignExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(AssignExprNode); DBG_STMT_TYPE(AssignExprNode);
}; };
@ -389,8 +386,8 @@ struct AssignOpExprNode : ExprNode
TypeReq subType; TypeReq subType;
static AssignOpExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op ); static AssignOpExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(AssignOpExprNode); DBG_STMT_TYPE(AssignOpExprNode);
}; };
@ -402,8 +399,8 @@ struct TTagSetStmtNode : StmtNode
ExprNode *stringExpr; ExprNode *stringExpr;
static TTagSetStmtNode *alloc( S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr ); static TTagSetStmtNode *alloc( S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr );
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
DBG_STMT_TYPE(TTagSetStmtNode); DBG_STMT_TYPE(TTagSetStmtNode);
}; };
@ -412,8 +409,8 @@ struct TTagDerefNode : ExprNode
ExprNode *expr; ExprNode *expr;
static TTagDerefNode *alloc( S32 lineNumber, ExprNode *expr ); static TTagDerefNode *alloc( S32 lineNumber, ExprNode *expr );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(TTagDerefNode); DBG_STMT_TYPE(TTagDerefNode);
}; };
@ -423,8 +420,8 @@ struct TTagExprNode : ExprNode
StringTableEntry tag; StringTableEntry tag;
static TTagExprNode *alloc( S32 lineNumber, StringTableEntry tag ); static TTagExprNode *alloc( S32 lineNumber, StringTableEntry tag );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(TTagExprNode); DBG_STMT_TYPE(TTagExprNode);
}; };
@ -442,8 +439,8 @@ struct FuncCallExprNode : ExprNode
}; };
static FuncCallExprNode *alloc( S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot ); static FuncCallExprNode *alloc( S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FuncCallExprNode); DBG_STMT_TYPE(FuncCallExprNode);
}; };
@ -455,8 +452,8 @@ struct AssertCallExprNode : ExprNode
U32 messageIndex; U32 messageIndex;
static AssertCallExprNode *alloc( S32 lineNumber, ExprNode *testExpr, const char *message ); static AssertCallExprNode *alloc( S32 lineNumber, ExprNode *testExpr, const char *message );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(AssertCallExprNode); DBG_STMT_TYPE(AssertCallExprNode);
}; };
@ -475,8 +472,8 @@ struct SlotAccessNode : ExprNode
StringTableEntry slotName; StringTableEntry slotName;
static SlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName ); static SlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(SlotAccessNode); DBG_STMT_TYPE(SlotAccessNode);
}; };
@ -495,8 +492,8 @@ struct InternalSlotAccessNode : ExprNode
bool recurse; bool recurse;
static InternalSlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse ); static InternalSlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(InternalSlotAccessNode); DBG_STMT_TYPE(InternalSlotAccessNode);
}; };
@ -509,8 +506,8 @@ struct SlotAssignNode : ExprNode
U32 typeID; U32 typeID;
static SlotAssignNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1 ); static SlotAssignNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1 );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(SlotAssignNode); DBG_STMT_TYPE(SlotAssignNode);
}; };
@ -525,8 +522,8 @@ struct SlotAssignOpNode : ExprNode
TypeReq subType; TypeReq subType;
static SlotAssignOpNode *alloc( S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr ); static SlotAssignOpNode *alloc( S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr );
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(SlotAssignOpNode); DBG_STMT_TYPE(SlotAssignOpNode);
}; };
@ -545,10 +542,10 @@ struct ObjectDeclNode : ExprNode
bool isSingleton; bool isSingleton;
static ObjectDeclNode *alloc( S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton ); static ObjectDeclNode *alloc( S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton );
U32 precompile(TypeReq type);
U32 precompileSubObject(bool); U32 precompileSubObject(bool);
U32 compile(U32 *codeStream, U32 ip, TypeReq type); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
U32 compileSubObject(U32 *codeStream, U32 ip, bool); U32 compileSubObject(CodeStream &codeStream, U32 ip, bool);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(ObjectDeclNode); DBG_STMT_TYPE(ObjectDeclNode);
}; };
@ -570,18 +567,13 @@ struct FunctionDeclStmtNode : StmtNode
U32 argc; U32 argc;
static FunctionDeclStmtNode *alloc( S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts ); static FunctionDeclStmtNode *alloc( S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts );
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileStmt(CodeStream &codeStream, U32 ip);
void setPackage(StringTableEntry packageName); void setPackage(StringTableEntry packageName);
DBG_STMT_TYPE(FunctionDeclStmtNode); DBG_STMT_TYPE(FunctionDeclStmtNode);
}; };
extern StmtNode *gStatementList; extern StmtNode *gStatementList;
extern void createFunction(const char *fnName, VarNode *args, StmtNode *statements); extern ExprEvalState gEvalState;;
extern ExprEvalState gEvalState;
extern bool lookupFunction(const char *fnName, VarNode **args, StmtNode **statements);
typedef const char *(*cfunc)(S32 argc, char **argv);
extern bool lookupCFunction(const char *fnName, cfunc *f);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -33,7 +33,6 @@
using namespace Compiler; using namespace Compiler;
bool CodeBlock::smInFunction = false; bool CodeBlock::smInFunction = false;
U32 CodeBlock::smBreakLineCount = 0;
CodeBlock * CodeBlock::smCodeBlockList = NULL; CodeBlock * CodeBlock::smCodeBlockList = NULL;
CodeBlock * CodeBlock::smCurrentCodeBlock = NULL; CodeBlock * CodeBlock::smCurrentCodeBlock = NULL;
ConsoleParser *CodeBlock::smCurrentParser = NULL; ConsoleParser *CodeBlock::smCurrentParser = NULL;
@ -456,6 +455,8 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st)
bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, const char *inScript, bool overrideNoDso) bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, const char *inScript, bool overrideNoDso)
{ {
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
// This will return true, but return value is ignored // This will return true, but return value is ignored
char *script; char *script;
chompUTF8BOM( inScript, &script ); chompUTF8BOM( inScript, &script );
@ -464,7 +465,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
consoleAllocReset(); consoleAllocReset();
STEtoU32 = compileSTEtoU32; STEtoCode = compileSTEtoCode;
gStatementList = NULL; gStatementList = NULL;
@ -497,17 +498,23 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
resetTables(); resetTables();
smInFunction = false; smInFunction = false;
smBreakLineCount = 0;
setBreakCodeBlock(this);
CodeStream codeStream;
U32 lastIp;
if(gStatementList) if(gStatementList)
codeSize = precompileBlock(gStatementList, 0) + 1; {
lastIp = compileBlock(gStatementList, codeStream, 0) + 1;
}
else else
{
codeSize = 1; codeSize = 1;
lastIp = 0;
lineBreakPairCount = smBreakLineCount; }
code = new U32[codeSize + smBreakLineCount * 2];
lineBreakPairs = code + codeSize; codeStream.emit(OP_RETURN);
codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs);
lineBreakPairCount = codeStream.getNumLineBreaks();
// Write string table data... // Write string table data...
getGlobalStringTable().write(st); getGlobalStringTable().write(st);
@ -517,18 +524,10 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
getGlobalFloatTable().write(st); getGlobalFloatTable().write(st);
getFunctionFloatTable().write(st); getFunctionFloatTable().write(st);
smBreakLineCount = 0; if(lastIp != codeSize)
U32 lastIp;
if(gStatementList)
lastIp = compileBlock(gStatementList, code, 0, 0, 0);
else
lastIp = 0;
if(lastIp != codeSize - 1)
Con::errorf(ConsoleLogEntry::General, "CodeBlock::compile - precompile size mismatch, a precompile/compile function pair is probably mismatched."); Con::errorf(ConsoleLogEntry::General, "CodeBlock::compile - precompile size mismatch, a precompile/compile function pair is probably mismatched.");
code[lastIp++] = OP_RETURN; U32 totSize = codeSize + codeStream.getNumLineBreaks() * 2;
U32 totSize = codeSize + smBreakLineCount * 2;
st.write(codeSize); st.write(codeSize);
st.write(lineBreakPairCount); st.write(lineBreakPairCount);
@ -561,11 +560,13 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame) const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
{ {
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
// Check for a UTF8 script file // Check for a UTF8 script file
char *string; char *string;
chompUTF8BOM( inString, &string ); chompUTF8BOM( inString, &string );
STEtoU32 = evalSTEtoU32; STEtoCode = evalSTEtoCode;
consoleAllocReset(); consoleAllocReset();
name = fileName; name = fileName;
@ -617,12 +618,11 @@ const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inStri
resetTables(); resetTables();
smInFunction = false; smInFunction = false;
smBreakLineCount = 0;
setBreakCodeBlock(this); CodeStream codeStream;
U32 lastIp = compileBlock(gStatementList, codeStream, 0);
codeSize = precompileBlock(gStatementList, 0) + 1; lineBreakPairCount = codeStream.getNumLineBreaks();
lineBreakPairCount = smBreakLineCount;
globalStrings = getGlobalStringTable().build(); globalStrings = getGlobalStringTable().build();
globalStringsMaxLen = getGlobalStringTable().totalLen; globalStringsMaxLen = getGlobalStringTable().totalLen;
@ -632,20 +632,18 @@ const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inStri
globalFloats = getGlobalFloatTable().build(); globalFloats = getGlobalFloatTable().build();
functionFloats = getFunctionFloatTable().build(); functionFloats = getFunctionFloatTable().build();
code = new U32[codeSize + lineBreakPairCount * 2]; codeStream.emit(OP_RETURN);
lineBreakPairs = code + codeSize; codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs);
smBreakLineCount = 0; //dumpInstructions(0, false);
U32 lastIp = compileBlock(gStatementList, code, 0, 0, 0);
code[lastIp++] = OP_RETURN;
consoleAllocReset(); consoleAllocReset();
if(lineBreakPairCount && fileName) if(lineBreakPairCount && fileName)
calcBreakList(); calcBreakList();
if(lastIp != 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); return exec(0, fileName, NULL, 0, 0, noCalls, NULL, setFrame);
@ -674,7 +672,7 @@ String CodeBlock::getFunctionArgs( U32 ip )
U32 fnArgc = code[ ip + 5 ]; U32 fnArgc = code[ ip + 5 ];
for( U32 i = 0; i < fnArgc; ++ i ) for( U32 i = 0; i < fnArgc; ++ i )
{ {
StringTableEntry var = U32toSTE( code[ ip + i + 6 ] ); StringTableEntry var = CodeToSTE(code, ip + (i*2) + 6);
if( i != 0 ) if( i != 0 )
str.append( ", " ); str.append( ", " );
@ -696,41 +694,52 @@ String CodeBlock::getFunctionArgs( U32 ip )
void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
{ {
U32 ip = startIp; U32 ip = startIp;
smInFunction = false;
U32 endFuncIp = 0;
while( ip < codeSize ) while( ip < codeSize )
{ {
if (ip > endFuncIp)
{
smInFunction = false;
}
switch( code[ ip ++ ] ) switch( code[ ip ++ ] )
{ {
case OP_FUNC_DECL: case OP_FUNC_DECL:
{ {
StringTableEntry fnName = U32toSTE(code[ip]); StringTableEntry fnName = CodeToSTE(code, ip);
StringTableEntry fnNamespace = U32toSTE(code[ip+1]); StringTableEntry fnNamespace = CodeToSTE(code, ip+2);
StringTableEntry fnPackage = U32toSTE(code[ip+2]); StringTableEntry fnPackage = CodeToSTE(code, ip+4);
bool hasBody = bool(code[ip+3]); bool hasBody = bool(code[ip+6]);
U32 newIp = code[ ip + 4 ]; U32 newIp = code[ ip + 7 ];
U32 argc = code[ ip + 5 ]; U32 argc = code[ ip + 8 ];
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",
ip - 1, fnName, fnNamespace, fnPackage, hasBody, newIp, argc ); ip - 1, fnName, fnNamespace, fnPackage, hasBody, newIp, argc );
// Skip args. // Skip args.
ip += 6 + argc; ip += 9 + (argc * 2);
smInFunction = true;
break; break;
} }
case OP_CREATE_OBJECT: case OP_CREATE_OBJECT:
{ {
StringTableEntry objParent = U32toSTE(code[ip ]); StringTableEntry objParent = CodeToSTE(code, ip);
bool isDataBlock = code[ip + 1]; bool isDataBlock = code[ip + 2];
bool isInternal = code[ip + 2]; bool isInternal = code[ip + 3];
bool isSingleton = code[ip + 3]; bool isSingleton = code[ip + 4];
U32 lineNumber = code[ip + 4]; U32 lineNumber = code[ip + 5];
U32 failJump = code[ip + 5]; U32 failJump = code[ip + 6];
Con::printf( "%i: OP_CREATE_OBJECT objParent=%s isDataBlock=%i isInternal=%i isSingleton=%i lineNumber=%i failJump=%i", Con::printf( "%i: OP_CREATE_OBJECT objParent=%s isDataBlock=%i isInternal=%i isSingleton=%i lineNumber=%i failJump=%i",
ip - 1, objParent, isDataBlock, isInternal, isSingleton, lineNumber, failJump ); ip - 1, objParent, isDataBlock, isInternal, isSingleton, lineNumber, failJump );
ip += 6; ip += 7;
break; break;
} }
@ -957,19 +966,19 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_SETCURVAR: case OP_SETCURVAR:
{ {
StringTableEntry var = U32toSTE(code[ip]); StringTableEntry var = CodeToSTE(code, ip);
Con::printf( "%i: OP_SETCURVAR var=%s", ip - 1, var ); Con::printf( "%i: OP_SETCURVAR var=%s", ip - 1, var );
ip++; ip += 2;
break; break;
} }
case OP_SETCURVAR_CREATE: case OP_SETCURVAR_CREATE:
{ {
StringTableEntry var = U32toSTE(code[ip]); StringTableEntry var = CodeToSTE(code, ip);
Con::printf( "%i: OP_SETCURVAR_CREATE var=%s", ip - 1, var ); Con::printf( "%i: OP_SETCURVAR_CREATE var=%s", ip - 1, var );
ip++; ip += 2;
break; break;
} }
@ -1042,9 +1051,10 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_SETCURFIELD: case OP_SETCURFIELD:
{ {
StringTableEntry curField = U32toSTE(code[ip]); StringTableEntry curField = CodeToSTE(code, ip);
Con::printf( "%i: OP_SETCURFIELD field=%s", ip - 1, curField ); Con::printf( "%i: OP_SETCURFIELD field=%s", ip - 1, curField );
++ ip; ip += 2;
break;
} }
case OP_SETCURFIELD_ARRAY: case OP_SETCURFIELD_ARRAY:
@ -1161,7 +1171,7 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_LOADIMMED_FLT: case OP_LOADIMMED_FLT:
{ {
F64 val = functionFloats[ code[ ip ] ]; F64 val = (smInFunction ? functionFloats : globalFloats)[ code[ ip ] ];
Con::printf( "%i: OP_LOADIMMED_FLT val=%f", ip - 1, val ); Con::printf( "%i: OP_LOADIMMED_FLT val=%f", ip - 1, val );
++ ip; ++ ip;
break; break;
@ -1169,7 +1179,7 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_TAG_TO_STR: case OP_TAG_TO_STR:
{ {
const char* str = functionStrings + code[ ip ]; const char* str = (smInFunction ? functionStrings : globalStrings) + code[ ip ];
Con::printf( "%i: OP_TAG_TO_STR str=%s", ip - 1, str ); Con::printf( "%i: OP_TAG_TO_STR str=%s", ip - 1, str );
++ ip; ++ ip;
break; break;
@ -1177,7 +1187,7 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_LOADIMMED_STR: case OP_LOADIMMED_STR:
{ {
const char* str = functionStrings + code[ ip ]; const char* str = (smInFunction ? functionStrings : globalStrings) + code[ ip ];
Con::printf( "%i: OP_LOADIMMED_STR str=%s", ip - 1, str ); Con::printf( "%i: OP_LOADIMMED_STR str=%s", ip - 1, str );
++ ip; ++ ip;
break; break;
@ -1185,7 +1195,7 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_DOCBLOCK_STR: case OP_DOCBLOCK_STR:
{ {
const char* str = functionStrings + code[ ip ]; const char* str = (smInFunction ? functionStrings : globalStrings) + code[ ip ];
Con::printf( "%i: OP_DOCBLOCK_STR str=%s", ip - 1, str ); Con::printf( "%i: OP_DOCBLOCK_STR str=%s", ip - 1, str );
++ ip; ++ ip;
break; break;
@ -1193,37 +1203,37 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_LOADIMMED_IDENT: case OP_LOADIMMED_IDENT:
{ {
StringTableEntry str = U32toSTE( code[ ip ] ); StringTableEntry str = CodeToSTE(code, ip);
Con::printf( "%i: OP_LOADIMMED_IDENT str=%s", ip - 1, str ); Con::printf( "%i: OP_LOADIMMED_IDENT str=%s", ip - 1, str );
++ ip; ip += 2;
break; break;
} }
case OP_CALLFUNC_RESOLVE: case OP_CALLFUNC_RESOLVE:
{ {
StringTableEntry fnNamespace = U32toSTE(code[ip+1]); StringTableEntry fnNamespace = CodeToSTE(code, ip+2);
StringTableEntry fnName = U32toSTE(code[ip]); StringTableEntry fnName = CodeToSTE(code, ip);
U32 callType = code[ip+2]; U32 callType = code[ip+2];
Con::printf( "%i: OP_CALLFUNC_RESOLVE name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, Con::printf( "%i: OP_CALLFUNC_RESOLVE name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace,
callType == FuncCallExprNode::FunctionCall ? "FunctionCall" callType == FuncCallExprNode::FunctionCall ? "FunctionCall"
: callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall" ); : callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall" );
ip += 3; ip += 5;
break; break;
} }
case OP_CALLFUNC: case OP_CALLFUNC:
{ {
StringTableEntry fnNamespace = U32toSTE(code[ip+1]); StringTableEntry fnNamespace = CodeToSTE(code, ip+2);
StringTableEntry fnName = U32toSTE(code[ip]); StringTableEntry fnName = CodeToSTE(code, ip);
U32 callType = code[ip+2]; U32 callType = code[ip+4];
Con::printf( "%i: OP_CALLFUNC name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, Con::printf( "%i: OP_CALLFUNC name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace,
callType == FuncCallExprNode::FunctionCall ? "FunctionCall" callType == FuncCallExprNode::FunctionCall ? "FunctionCall"
: callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall" ); : callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall" );
ip += 3; ip += 5;
break; break;
} }
@ -1285,7 +1295,7 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_ASSERT: case OP_ASSERT:
{ {
const char* message = functionStrings + code[ ip ]; const char* message = (smInFunction ? functionStrings : globalStrings) + code[ ip ];
Con::printf( "%i: OP_ASSERT message=%s", ip - 1, message ); Con::printf( "%i: OP_ASSERT message=%s", ip - 1, message );
++ ip; ++ ip;
break; break;
@ -1299,31 +1309,34 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
case OP_ITER_BEGIN: case OP_ITER_BEGIN:
{ {
StringTableEntry varName = U32toSTE( code[ ip ] ); StringTableEntry varName = CodeToSTE(code, ip);
U32 failIp = code[ ip + 1 ]; U32 failIp = code[ ip + 2 ];
Con::printf( "%i: OP_ITER_BEGIN varName=%s failIp=%i", varName, failIp ); Con::printf( "%i: OP_ITER_BEGIN varName=%s failIp=%i", ip - 1, varName, failIp );
++ ip; ip += 3;
break;
} }
case OP_ITER_BEGIN_STR: case OP_ITER_BEGIN_STR:
{ {
StringTableEntry varName = U32toSTE( code[ ip ] ); StringTableEntry varName = CodeToSTE(code, ip);
U32 failIp = code[ ip + 1 ]; U32 failIp = code[ ip + 2 ];
Con::printf( "%i: OP_ITER_BEGIN varName=%s failIp=%i", varName, failIp ); Con::printf( "%i: OP_ITER_BEGIN varName=%s failIp=%i", ip - 1, varName, failIp );
ip += 2; ip += 3;
break;
} }
case OP_ITER: case OP_ITER:
{ {
U32 breakIp = code[ ip ]; U32 breakIp = code[ ip ];
Con::printf( "%i: OP_ITER breakIp=%i", breakIp ); Con::printf( "%i: OP_ITER breakIp=%i", ip - 1, breakIp );
++ ip; ++ ip;
break;
} }
case OP_ITER_END: case OP_ITER_END:
@ -1337,4 +1350,6 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
break; break;
} }
} }
smInFunction = false;
} }

View file

@ -38,7 +38,6 @@ private:
static CodeBlock* smCurrentCodeBlock; static CodeBlock* smCurrentCodeBlock;
public: public:
static U32 smBreakLineCount;
static bool smInFunction; static bool smInFunction;
static Compiler::ConsoleParser * smCurrentParser; static Compiler::ConsoleParser * smCurrentParser;

View file

@ -45,6 +45,9 @@
#include "materials/materialManager.h" #include "materials/materialManager.h"
#endif #endif
// Uncomment to optimize function calls at the expense of potential invalid package lookups
//#define COMPILER_OPTIMIZE_FUNCTION_CALLS
using namespace Compiler; using namespace Compiler;
enum EvalConstants { enum EvalConstants {
@ -422,8 +425,8 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
if(argv) if(argv)
{ {
// assume this points into a function decl: // assume this points into a function decl:
U32 fnArgc = code[ip + 5]; U32 fnArgc = code[ip + 2 + 6];
thisFunctionName = U32toSTE(code[ip]); thisFunctionName = CodeToSTE(code, ip);
argc = getMin(argc-1, fnArgc); // argv[0] is func name argc = getMin(argc-1, fnArgc); // argv[0] is func name
if(gEvalState.traceOn) if(gEvalState.traceOn)
{ {
@ -458,11 +461,11 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
popFrame = true; popFrame = true;
for(i = 0; i < argc; i++) for(i = 0; i < argc; i++)
{ {
StringTableEntry var = U32toSTE(code[ip + i + 6]); StringTableEntry var = CodeToSTE(code, ip + (2 + 6 + 1) + (i * 2));
gEvalState.setCurVarNameCreate(var); gEvalState.setCurVarNameCreate(var);
gEvalState.setStringVariable(argv[i+1]); gEvalState.setStringVariable(argv[i+1]);
} }
ip = ip + fnArgc + 6; ip = ip + (fnArgc * 2) + (2 + 6 + 1);
curFloatTable = functionFloats; curFloatTable = functionFloats;
curStringTable = functionStrings; curStringTable = functionStrings;
curStringTableLen = functionStringsMaxLen; curStringTableLen = functionStringsMaxLen;
@ -559,11 +562,11 @@ breakContinue:
case OP_FUNC_DECL: case OP_FUNC_DECL:
if(!noCalls) if(!noCalls)
{ {
fnName = U32toSTE(code[ip]); fnName = CodeToSTE(code, ip);
fnNamespace = U32toSTE(code[ip+1]); fnNamespace = CodeToSTE(code, ip+2);
fnPackage = U32toSTE(code[ip+2]); fnPackage = CodeToSTE(code, ip+4);
bool hasBody = ( code[ ip + 3 ] & 0x01 ) != 0; bool hasBody = ( code[ ip + 6 ] & 0x01 ) != 0;
U32 lineNumber = code[ ip + 3 ] >> 1; U32 lineNumber = code[ ip + 6 ] >> 1;
Namespace::unlinkPackages(); Namespace::unlinkPackages();
ns = Namespace::find(fnNamespace, fnPackage); ns = Namespace::find(fnNamespace, fnPackage);
@ -586,18 +589,18 @@ breakContinue:
//Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip); //Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip);
} }
ip = code[ip + 4]; ip = code[ip + 7];
break; break;
case OP_CREATE_OBJECT: case OP_CREATE_OBJECT:
{ {
// Read some useful info. // Read some useful info.
objParent = U32toSTE(code[ip ]); objParent = CodeToSTE(code, ip);
bool isDataBlock = code[ip + 1]; bool isDataBlock = code[ip + 2];
bool isInternal = code[ip + 2]; bool isInternal = code[ip + 3];
bool isSingleton = code[ip + 3]; bool isSingleton = code[ip + 4];
U32 lineNumber = code[ip + 4]; U32 lineNumber = code[ip + 5];
failJump = code[ip + 5]; failJump = code[ip + 6];
// If we don't allow calls, we certainly don't allow creating objects! // If we don't allow calls, we certainly don't allow creating objects!
// Moved this to after failJump is set. Engine was crashing when // Moved this to after failJump is set. Engine was crashing when
@ -848,7 +851,7 @@ breakContinue:
} }
// Advance the IP past the create info... // Advance the IP past the create info...
ip += 6; ip += 7;
break; break;
} }
@ -1170,8 +1173,8 @@ breakContinue:
break; break;
case OP_SETCURVAR: case OP_SETCURVAR:
var = U32toSTE(code[ip]); var = CodeToSTE(code, ip);
ip++; ip += 2;
// If a variable is set, then these must be NULL. It is necessary // If a variable is set, then these must be NULL. It is necessary
// to set this here so that the vector parser can appropriately // to set this here so that the vector parser can appropriately
@ -1190,8 +1193,8 @@ breakContinue:
break; break;
case OP_SETCURVAR_CREATE: case OP_SETCURVAR_CREATE:
var = U32toSTE(code[ip]); var = CodeToSTE(code, ip);
ip++; ip += 2;
// See OP_SETCURVAR // See OP_SETCURVAR
prevField = NULL; prevField = NULL;
@ -1310,9 +1313,9 @@ breakContinue:
// Save the previous field for parsing vector fields. // Save the previous field for parsing vector fields.
prevField = curField; prevField = curField;
dStrcpy( prevFieldArray, curFieldArray ); dStrcpy( prevFieldArray, curFieldArray );
curField = U32toSTE(code[ip]); curField = CodeToSTE(code, ip);
curFieldArray[0] = 0; curFieldArray[0] = 0;
ip++; ip += 2;
break; break;
case OP_SETCURFIELD_ARRAY: case OP_SETCURFIELD_ARRAY:
@ -1504,28 +1507,40 @@ breakContinue:
break; break;
case OP_LOADIMMED_IDENT: case OP_LOADIMMED_IDENT:
STR.setStringValue(U32toSTE(code[ip++])); STR.setStringValue(CodeToSTE(code, ip));
ip += 2;
break; break;
case OP_CALLFUNC_RESOLVE: case OP_CALLFUNC_RESOLVE:
// This deals with a function that is potentially living in a namespace. // This deals with a function that is potentially living in a namespace.
fnNamespace = U32toSTE(code[ip+1]); fnNamespace = CodeToSTE(code, ip+2);
fnName = U32toSTE(code[ip]); fnName = CodeToSTE(code, ip);
// Try to look it up. // Try to look it up.
ns = Namespace::find(fnNamespace); ns = Namespace::find(fnNamespace);
nsEntry = ns->lookup(fnName); nsEntry = ns->lookup(fnName);
if(!nsEntry) if(!nsEntry)
{ {
ip+= 3; ip+= 5;
Con::warnf(ConsoleLogEntry::General, Con::warnf(ConsoleLogEntry::General,
"%s: Unable to find function %s%s%s", "%s: Unable to find function %s%s%s",
getFileLine(ip-4), fnNamespace ? fnNamespace : "", getFileLine(ip-7), fnNamespace ? fnNamespace : "",
fnNamespace ? "::" : "", fnName); fnNamespace ? "::" : "", fnName);
STR.popFrame(); STR.popFrame();
break; break;
} }
#ifdef COMPILER_OPTIMIZE_FUNCTION_CALLS
// Now fall through to OP_CALLFUNC... // Now fall through to OP_CALLFUNC...
// Now, rewrite our code a bit (ie, avoid future lookups) and fall
// through to OP_CALLFUNC
#ifdef TORQUE_CPU_X64
*((U64*)(code+ip+2)) = ((U64)nsEntry);
#else
code[ip+2] = ((U32)nsEntry);
#endif
code[ip-1] = OP_CALLFUNC;
#endif
case OP_CALLFUNC: case OP_CALLFUNC:
{ {
@ -1535,7 +1550,7 @@ breakContinue:
// or just on the object. // or just on the object.
S32 routingId = 0; S32 routingId = 0;
fnName = U32toSTE(code[ip]); fnName = CodeToSTE(code, ip);
//if this is called from inside a function, append the ip and codeptr //if this is called from inside a function, append the ip and codeptr
if( gEvalState.getStackDepth() > 0 ) if( gEvalState.getStackDepth() > 0 )
@ -1544,9 +1559,9 @@ breakContinue:
gEvalState.getCurrentFrame().ip = ip - 1; gEvalState.getCurrentFrame().ip = ip - 1;
} }
U32 callType = code[ip+2]; U32 callType = code[ip+4];
ip += 3; ip += 5;
STR.getArgcArgv(fnName, &callArgc, &callArgv); STR.getArgcArgv(fnName, &callArgc, &callArgv);
const char *componentReturnValue = ""; const char *componentReturnValue = "";
@ -1555,9 +1570,16 @@ breakContinue:
{ {
if( !nsEntry ) if( !nsEntry )
{ {
// We must not have come from OP_CALLFUNC_RESOLVE, so figure out #ifdef COMPILER_OPTIMIZE_FUNCTION_CALLS
// our own entry. #ifdef TORQUE_CPU_X64
nsEntry = ((Namespace::Entry *) *((U64*)(code+ip-3)));
#else
nsEntry = ((Namespace::Entry *) *(code+ip-3));
#endif
#else
nsEntry = Namespace::global()->lookup( fnName ); nsEntry = Namespace::global()->lookup( fnName );
#endif
ns = NULL;
} }
ns = NULL; ns = NULL;
} }
@ -1618,7 +1640,7 @@ breakContinue:
{ {
if(!noCalls && !( routingId == MethodOnComponent ) ) if(!noCalls && !( routingId == MethodOnComponent ) )
{ {
Con::warnf(ConsoleLogEntry::General,"%s: Unknown command %s.", getFileLine(ip-4), fnName); Con::warnf(ConsoleLogEntry::General,"%s: Unknown command %s.", getFileLine(ip-6), fnName);
if(callType == FuncCallExprNode::MethodCall) if(callType == FuncCallExprNode::MethodCall)
{ {
Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s", Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s",
@ -1652,16 +1674,16 @@ breakContinue:
// which is useful behavior when debugging so I'm ifdefing this out for debug builds. // which is useful behavior when debugging so I'm ifdefing this out for debug builds.
if(nsEntry->mToolOnly && ! Con::isCurrentScriptToolScript()) if(nsEntry->mToolOnly && ! Con::isCurrentScriptToolScript())
{ {
Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", getFileLine(ip-4), nsName, fnName); Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", getFileLine(ip-6), nsName, fnName);
} }
else else
#endif #endif
if((nsEntry->mMinArgs && S32(callArgc) < nsEntry->mMinArgs) || (nsEntry->mMaxArgs && S32(callArgc) > nsEntry->mMaxArgs)) if((nsEntry->mMinArgs && S32(callArgc) < nsEntry->mMinArgs) || (nsEntry->mMaxArgs && S32(callArgc) > nsEntry->mMaxArgs))
{ {
Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).", Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).",
getFileLine(ip-4), nsName, fnName, getFileLine(ip-6), nsName, fnName,
callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs); callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs);
Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-4), nsEntry->mUsage); Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-6), nsEntry->mUsage);
STR.popFrame(); STR.popFrame();
} }
else else
@ -1725,7 +1747,7 @@ breakContinue:
case Namespace::Entry::VoidCallbackType: case Namespace::Entry::VoidCallbackType:
nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv); nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
if( code[ ip ] != OP_STR_TO_NONE && Con::getBoolVariable( "$Con::warnVoidAssignment", true ) ) if( code[ ip ] != OP_STR_TO_NONE && Con::getBoolVariable( "$Con::warnVoidAssignment", true ) )
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-4), fnName, functionName); Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-6), fnName, functionName);
STR.popFrame(); STR.popFrame();
STR.setStringValue(""); STR.setStringValue("");
@ -1844,8 +1866,8 @@ breakContinue:
case OP_ITER_BEGIN: case OP_ITER_BEGIN:
{ {
StringTableEntry varName = U32toSTE( code[ ip ] ); StringTableEntry varName = CodeToSTE(code, ip);
U32 failIp = code[ ip + 1 ]; U32 failIp = code[ ip + 2 ];
IterStackRecord& iter = iterStack[ _ITER ]; IterStackRecord& iter = iterStack[ _ITER ];
@ -1880,7 +1902,7 @@ breakContinue:
STR.push(); STR.push();
ip += 2; ip += 3;
break; break;
} }

View file

@ -60,60 +60,27 @@ namespace Compiler
CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable; CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable;
DataChunker gConsoleAllocator; DataChunker gConsoleAllocator;
CompilerIdentTable gIdentTable; CompilerIdentTable gIdentTable;
CodeBlock *gCurBreakBlock;
//------------------------------------------------------------ //------------------------------------------------------------
void evalSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr)
CodeBlock *getBreakCodeBlock() { return gCurBreakBlock; }
void setBreakCodeBlock(CodeBlock *cb) { gCurBreakBlock = cb; }
//------------------------------------------------------------
#ifdef TORQUE_CPU_X64
// Fixed unsafe conversion from pointer to U32. @todo x64 revise
U32 u32toSTEId = 0;
typedef Map< U32, StringTableEntry > U32toSteMap;
U32toSteMap u32toSTEMap;
StringTableEntry U32toSTE( U32 u )
{
// @todo x64 Added thread-safe convertion.
const U32toSteMap::Iterator result = u32toSTEMap.find( u );
AssertFatal( result != u32toSTEMap.end( ),
"Don't converted U32 to STE. See evalSTEtoU32()." );
return result->value;
}
U32 evalSTEtoU32( StringTableEntry ste, U32 )
{
// @todo x64 Added thread-safe convertion.
u32toSTEMap.insert( u32toSTEId++, ste );
return (u32toSTEId - 1); // pointer to inserted
}
#else
StringTableEntry U32toSTE(U32 u)
{
return *((StringTableEntry *) &u);
}
U32 evalSTEtoU32(StringTableEntry ste, U32)
{ {
return *((U32 *) &ste); #ifdef TORQUE_64
} *((U64*)(ptr) = (U64)ste;
#else
*ptr = (U32)ste;
#endif #endif
}
U32 compileSTEtoU32(StringTableEntry ste, U32 ip)
void compileSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr)
{ {
if(ste) if(ste)
getIdentTable().add(ste, ip); getIdentTable().add(ste, ip);
return 0; *ptr = 0;
*(ptr+1) = 0;
} }
U32 (*STEtoU32)(StringTableEntry ste, U32 ip) = evalSTEtoU32; void (*STEtoCode)(StringTableEntry ste, U32 ip, U32 *ptr) = evalSTEtoCode;
//------------------------------------------------------------ //------------------------------------------------------------
@ -317,3 +284,131 @@ void CompilerIdentTable::write(Stream &st)
st.write(el->ip); st.write(el->ip);
} }
} }
//-------------------------------------------------------------------------
U8 *CodeStream::allocCode(U32 sz)
{
U8 *ptr = NULL;
if (mCodeHead)
{
const U32 bytesLeft = BlockSize - mCodeHead->size;
if (bytesLeft > sz)
{
ptr = mCodeHead->data + mCodeHead->size;
mCodeHead->size += sz;
return ptr;
}
}
CodeData *data = new CodeData;
data->data = (U8*)dMalloc(BlockSize);
data->size = sz;
data->next = NULL;
if (mCodeHead)
mCodeHead->next = data;
mCodeHead = data;
if (mCode == NULL)
mCode = data;
return data->data;
}
//-------------------------------------------------------------------------
void CodeStream::fixLoop(U32 loopBlockStart, U32 breakPoint, U32 continuePoint)
{
AssertFatal(mFixStack.size() > 0, "Fix stack mismatch");
U32 fixStart = mFixStack[mFixStack.size()-1];
for (U32 i=fixStart; i<mFixList.size(); i += 2)
{
FixType type = (FixType)mFixList[i+1];
U32 fixedIp = 0;
bool valid = true;
switch (type)
{
case FIXTYPE_LOOPBLOCKSTART:
fixedIp = loopBlockStart;
break;
case FIXTYPE_BREAK:
fixedIp = breakPoint;
break;
case FIXTYPE_CONTINUE:
fixedIp = continuePoint;
break;
default:
//Con::warnf("Address %u fixed as %u", mFixList[i], mFixList[i+1]);
valid = false;
break;
}
if (valid)
{
patch(mFixList[i], fixedIp);
}
}
}
//-------------------------------------------------------------------------
void CodeStream::emitCodeStream(U32 *size, U32 **stream, U32 **lineBreaks)
{
// Alloc stream
U32 numLineBreaks = getNumLineBreaks();
*stream = new U32[mCodePos + (numLineBreaks * 2)];
dMemset(*stream, '\0', mCodePos + (numLineBreaks * 2));
*size = mCodePos;
// Dump chunks & line breaks
U32 outBytes = mCodePos * sizeof(U32);
U8 *outPtr = *((U8**)stream);
for (CodeData *itr = mCode; itr != NULL; itr = itr->next)
{
U32 bytesToCopy = itr->size > outBytes ? outBytes : itr->size;
dMemcpy(outPtr, itr->data, bytesToCopy);
outPtr += bytesToCopy;
outBytes -= bytesToCopy;
}
*lineBreaks = *stream + mCodePos;
dMemcpy(*lineBreaks, mBreakLines.address(), sizeof(U32) * mBreakLines.size());
// Apply patches on top
for (U32 i=0; i<mPatchList.size(); i++)
{
PatchEntry &e = mPatchList[i];
(*stream)[e.addr] = e.value;
}
}
//-------------------------------------------------------------------------
void CodeStream::reset()
{
mCodePos = 0;
mFixStack.clear();
mFixLoopStack.clear();
mFixList.clear();
mBreakLines.clear();
// Pop down to one code block
CodeData *itr = mCode ? mCode->next : NULL;
while (itr != NULL)
{
CodeData *next = itr->next;
dFree(itr->data);
dFree(itr);
itr = next;
}
if (mCode)
{
mCode->size = 0;
mCode->next = NULL;
mCodeHead = mCode;
}
}

View file

@ -24,6 +24,12 @@
#ifndef _COMPILER_H_ #ifndef _COMPILER_H_
#define _COMPILER_H_ #define _COMPILER_H_
//#define DEBUG_CODESTREAM
#ifdef DEBUG_CODESTREAM
#include <stdio.h>
#endif
class Stream; class Stream;
class DataChunker; class DataChunker;
@ -31,6 +37,9 @@ class DataChunker;
#include "console/ast.h" #include "console/ast.h"
#include "console/codeBlock.h" #include "console/codeBlock.h"
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
namespace Compiler namespace Compiler
{ {
@ -49,7 +58,7 @@ namespace Compiler
OP_JMPIFF, OP_JMPIFF,
OP_JMPIF, OP_JMPIF,
OP_JMPIFNOT_NP, OP_JMPIFNOT_NP,
OP_JMPIF_NP, OP_JMPIF_NP, // 10
OP_JMP, OP_JMP,
OP_RETURN, OP_RETURN,
// fixes a bug when not explicitly returning a value // fixes a bug when not explicitly returning a value
@ -60,7 +69,7 @@ namespace Compiler
OP_CMPLT, OP_CMPLT,
OP_CMPLE, OP_CMPLE,
OP_CMPNE, OP_CMPNE,
OP_XOR, OP_XOR, // 20
OP_MOD, OP_MOD,
OP_BITAND, OP_BITAND,
OP_BITOR, OP_BITOR,
@ -71,7 +80,7 @@ namespace Compiler
OP_SHR, OP_SHR,
OP_SHL, OP_SHL,
OP_AND, OP_AND,
OP_OR, OP_OR, // 30
OP_ADD, OP_ADD,
OP_SUB, OP_SUB,
@ -84,7 +93,7 @@ namespace Compiler
OP_SETCURVAR_ARRAY, OP_SETCURVAR_ARRAY,
OP_SETCURVAR_ARRAY_CREATE, OP_SETCURVAR_ARRAY_CREATE,
OP_LOADVAR_UINT, OP_LOADVAR_UINT,// 40
OP_LOADVAR_FLT, OP_LOADVAR_FLT,
OP_LOADVAR_STR, OP_LOADVAR_STR,
@ -97,7 +106,7 @@ namespace Compiler
OP_SETCUROBJECT_INTERNAL, OP_SETCUROBJECT_INTERNAL,
OP_SETCURFIELD, OP_SETCURFIELD,
OP_SETCURFIELD_ARRAY, OP_SETCURFIELD_ARRAY, // 50
OP_SETCURFIELD_TYPE, OP_SETCURFIELD_TYPE,
OP_LOADFIELD_UINT, OP_LOADFIELD_UINT,
@ -110,7 +119,7 @@ namespace Compiler
OP_STR_TO_UINT, OP_STR_TO_UINT,
OP_STR_TO_FLT, OP_STR_TO_FLT,
OP_STR_TO_NONE, OP_STR_TO_NONE, // 60
OP_FLT_TO_UINT, OP_FLT_TO_UINT,
OP_FLT_TO_STR, OP_FLT_TO_STR,
OP_FLT_TO_NONE, OP_FLT_TO_NONE,
@ -121,7 +130,7 @@ namespace Compiler
OP_LOADIMMED_UINT, OP_LOADIMMED_UINT,
OP_LOADIMMED_FLT, OP_LOADIMMED_FLT,
OP_TAG_TO_STR, OP_TAG_TO_STR,
OP_LOADIMMED_STR, OP_LOADIMMED_STR, // 70
OP_DOCBLOCK_STR, OP_DOCBLOCK_STR,
OP_LOADIMMED_IDENT, OP_LOADIMMED_IDENT,
@ -133,7 +142,7 @@ namespace Compiler
OP_ADVANCE_STR_COMMA, OP_ADVANCE_STR_COMMA,
OP_ADVANCE_STR_NUL, OP_ADVANCE_STR_NUL,
OP_REWIND_STR, OP_REWIND_STR,
OP_TERMINATE_REWIND_STR, OP_TERMINATE_REWIND_STR, // 80
OP_COMPARE_STR, OP_COMPARE_STR,
OP_PUSH, OP_PUSH,
@ -147,14 +156,14 @@ namespace Compiler
OP_ITER, ///< Enter foreach loop. OP_ITER, ///< Enter foreach loop.
OP_ITER_END, ///< End foreach loop. OP_ITER_END, ///< End foreach loop.
OP_INVALID OP_INVALID // 90
}; };
//------------------------------------------------------------ //------------------------------------------------------------
F64 consoleStringToNumber(const char *str, StringTableEntry file = 0, U32 line = 0); F64 consoleStringToNumber(const char *str, StringTableEntry file = 0, U32 line = 0);
U32 precompileBlock(StmtNode *block, U32 loopCount);
U32 compileBlock(StmtNode *block, U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint); U32 compileBlock(StmtNode *block, CodeStream &codeStream, U32 ip);
//------------------------------------------------------------ //------------------------------------------------------------
@ -218,12 +227,19 @@ namespace Compiler
//------------------------------------------------------------ //------------------------------------------------------------
StringTableEntry U32toSTE(U32 u); inline StringTableEntry CodeToSTE(U32 *code, U32 ip)
{
#ifdef TORQUE_CPU_X64
return (StringTableEntry)(*((U64*)(code+ip)));
#else
return (StringTableEntry)(*(code+ip));
#endif
}
extern U32 (*STEtoU32)(StringTableEntry ste, U32 ip); extern void (*STEtoCode)(StringTableEntry ste, U32 ip, U32 *ptr);
U32 evalSTEtoU32(StringTableEntry ste, U32); void evalSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr);
U32 compileSTEtoU32(StringTableEntry ste, U32 ip); void compileSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr);
CompilerStringTable *getCurrentStringTable(); CompilerStringTable *getCurrentStringTable();
CompilerStringTable &getGlobalStringTable(); CompilerStringTable &getGlobalStringTable();
@ -241,9 +257,6 @@ namespace Compiler
void precompileIdent(StringTableEntry ident); void precompileIdent(StringTableEntry ident);
CodeBlock *getBreakCodeBlock();
void setBreakCodeBlock(CodeBlock *cb);
/// Helper function to reset the float, string, and ident tables to a base /// Helper function to reset the float, string, and ident tables to a base
/// starting state. /// starting state.
void resetTables(); void resetTables();
@ -254,4 +267,170 @@ namespace Compiler
extern bool gSyntaxError; extern bool gSyntaxError;
}; };
/// Utility class to emit and patch bytecode
class CodeStream
{
public:
enum FixType
{
// For loops
FIXTYPE_LOOPBLOCKSTART,
FIXTYPE_BREAK,
FIXTYPE_CONTINUE
};
enum Constants
{
BlockSize = 16384,
};
protected:
typedef struct PatchEntry
{
U32 addr; ///< Address to patch
U32 value; ///< Value to place at addr
PatchEntry() {;}
PatchEntry(U32 a, U32 v) : addr(a), value(v) {;}
} PatchEntry;
typedef struct CodeData
{
U8 *data; ///< Allocated data (size is BlockSize)
U32 size; ///< Bytes used in data
CodeData *next; ///< Next block
};
/// @name Emitted code
/// {
CodeData *mCode;
CodeData *mCodeHead;
U32 mCodePos;
/// }
/// @name Code fixing stacks
/// {
Vector<U32> mFixList;
Vector<U32> mFixStack;
Vector<bool> mFixLoopStack;
Vector<PatchEntry> mPatchList;
/// }
Vector<U32> mBreakLines; ///< Line numbers
public:
CodeStream() : mCode(0), mCodeHead(NULL), mCodePos(0)
{
}
~CodeStream()
{
reset();
if (mCode)
{
dFree(mCode->data);
delete mCode;
}
}
U8 *allocCode(U32 sz);
inline U32 emit(U32 code)
{
U32 *ptr = (U32*)allocCode(4);
*ptr = code;
#ifdef DEBUG_CODESTREAM
printf("code[%u] = %u\n", mCodePos, code);
#endif
return mCodePos++;
}
inline void patch(U32 addr, U32 code)
{
#ifdef DEBUG_CODESTREAM
printf("patch[%u] = %u\n", addr, code);
#endif
mPatchList.push_back(PatchEntry(addr, code));
}
inline U32 emitSTE(const char *code)
{
U64 *ptr = (U64*)allocCode(8);
*ptr = 0;
Compiler::STEtoCode(code, mCodePos, (U32*)ptr);
#ifdef DEBUG_CODESTREAM
printf("code[%u] = %s\n", mCodePos, code);
#endif
mCodePos += 2;
return mCodePos-2;
}
inline U32 tell()
{
return mCodePos;
}
inline bool inLoop()
{
for (U32 i=0; i<mFixLoopStack.size(); i++)
{
if (mFixLoopStack[i])
return true;
}
return false;
}
inline U32 emitFix(FixType type)
{
U32 *ptr = (U32*)allocCode(4);
*ptr = (U32)type;
#ifdef DEBUG_CODESTREAM
printf("code[%u] = [FIX:%u]\n", mCodePos, (U32)type);
#endif
mFixList.push_back(mCodePos);
mFixList.push_back((U32)type);
return mCodePos++;
}
inline void pushFixScope(bool isLoop)
{
mFixStack.push_back(mFixList.size());
mFixLoopStack.push_back(isLoop);
}
inline void popFixScope()
{
AssertFatal(mFixStack.size() > 0, "Fix stack mismatch");
U32 newSize = mFixStack[mFixStack.size()-1];
while (mFixList.size() > newSize)
mFixList.pop_back();
mFixStack.pop_back();
mFixLoopStack.pop_back();
}
void fixLoop(U32 loopBlockStart, U32 breakPoint, U32 continuePoint);
inline void addBreakLine(U32 lineNumber, U32 ip)
{
mBreakLines.push_back(lineNumber);
mBreakLines.push_back(ip);
}
inline U32 getNumLineBreaks()
{
return mBreakLines.size() / 2;
}
void emitCodeStream(U32 *size, U32 **stream, U32 **lineBreaks);
void reset();
};
#endif #endif

View file

@ -182,7 +182,8 @@ namespace Con
/// 09/12/07 - CAF - 43->44 remove newmsg operator /// 09/12/07 - CAF - 43->44 remove newmsg operator
/// 09/27/07 - RDB - 44->45 Patch from Andreas Kirsch: Added opcode to support correct void return /// 09/27/07 - RDB - 44->45 Patch from Andreas Kirsch: Added opcode to support correct void return
/// 01/13/09 - TMS - 45->46 Added script assert /// 01/13/09 - TMS - 45->46 Added script assert
DSOVersion = 46, /// 09/07/14 - jamesu - 46->47 64bit support
DSOVersion = 47,
MaxLineLength = 512, ///< Maximum length of a line of console input. MaxLineLength = 512, ///< Maximum length of a line of console input.
MaxDataTypes = 256 ///< Maximum number of registered data types. MaxDataTypes = 256 ///< Maximum number of registered data types.

View file

@ -109,7 +109,7 @@ static const F32 F32_MAX = F32(3.402823466e+38F); ///< Constant
#endif #endif
/// Integral type matching the host's memory address width. /// Integral type matching the host's memory address width.
#ifdef TORQUE_64BITS #ifdef TORQUE_CPU_X64
typedef U64 MEM_ADDRESS; typedef U64 MEM_ADDRESS;
#else #else
typedef U32 MEM_ADDRESS; typedef U32 MEM_ADDRESS;