diff --git a/include/daScript/simulate/debug_info.h b/include/daScript/simulate/debug_info.h index fca06a419..01ced695b 100644 --- a/include/daScript/simulate/debug_info.h +++ b/include/daScript/simulate/debug_info.h @@ -8,7 +8,7 @@ namespace das #endif #ifndef DAS_ENABLE_KEEPALIVE -#define DAS_ENABLE_KEEPALIVE 0 +#define DAS_ENABLE_KEEPALIVE 1 #endif enum Type : int32_t { diff --git a/include/daScript/simulate/runtime_array.h b/include/daScript/simulate/runtime_array.h index 0cd56b8e6..8a13b0fcf 100644 --- a/include/daScript/simulate/runtime_array.h +++ b/include/daScript/simulate/runtime_array.h @@ -429,13 +429,13 @@ namespace das }; template <> - struct SimNodeKeepAlive_ForGoodArray1<0> : public SimNode_ForBase { - SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForBase(at) {} + struct SimNodeKeepAlive_ForGoodArray1<0> : public SimNode_ForGoodArray1<0> { + SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForGoodArray1<0>(at) {} }; template <> - struct SimNodeKeepAlive_ForGoodArray1<1> : public SimNode_ForBase { - SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForBase(at) {} + struct SimNodeKeepAlive_ForGoodArray1<1> : public SimNode_ForGoodArray1<1> { + SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForGoodArray1<1>(at) {} DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override { DAS_PROFILE_NODE Array * __restrict pha; diff --git a/include/daScript/simulate/simulate.h b/include/daScript/simulate/simulate.h index fad97805f..44441af80 100644 --- a/include/daScript/simulate/simulate.h +++ b/include/daScript/simulate/simulate.h @@ -122,6 +122,8 @@ namespace das virtual bool rtti_node_isInstrument() const { return false; } virtual bool rtti_node_isInstrumentFunction() const { return false; } virtual bool rtti_node_isJit() const { return false; } + virtual bool rtti_node_isKeepAlive() const { return false; } + virtual bool rtti_node_isCallBase() const { return false; } protected: virtual ~SimNode() {} }; @@ -988,6 +990,7 @@ __forceinline void profileNode ( SimNode * node ) { struct SimNode_KeepAlive : SimNode { SimNode_KeepAlive ( const LineInfo & at, SimNode * res ) : SimNode(at), value(res) {} + virtual bool rtti_node_isKeepAlive() const override { return true; } virtual SimNode * visit ( SimVisitor & vis ) override; #define EVAL_NODE(TYPE,CTYPE)\ virtual CTYPE eval##TYPE ( Context & context ) override { \ @@ -1008,6 +1011,7 @@ __forceinline void profileNode ( SimNode * node ) { // FUNCTION CALL struct SimNode_CallBase : SimNode { SimNode_CallBase ( const LineInfo & at ) : SimNode(at) {} + virtual bool rtti_node_isCallBase() const override { return true; } virtual SimNode * copyNode ( Context & context, NodeAllocator * code ) override; void visitCall ( SimVisitor & vis ); __forceinline void evalArgs ( Context & context, vec4f * argValues ) { diff --git a/src/ast/ast_simulate.cpp b/src/ast/ast_simulate.cpp index e33bf2d41..87677f068 100644 --- a/src/ast/ast_simulate.cpp +++ b/src/ast/ast_simulate.cpp @@ -114,14 +114,24 @@ namespace das // common for move and copy + SimNode_CallBase * getCallBase ( SimNode * node ) { + if ( node->rtti_node_isKeepAlive() ) { + SimNode_KeepAlive * ka = static_cast(node); + node = ka->value; + } + DAS_ASSERTF(node->rtti_node_isCallBase(),"we are calling getCallBase on a node, which is not a call base node." + "we should not be here, script compiler should have caught this during compilation."); + return static_cast(node); + } + SimNode * makeLocalCMResMove (const LineInfo & at, Context & context, uint32_t offset, const ExpressionPtr & rE ) { const auto & rightType = *rE->type; // now, call with CMRES if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, offset); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, offset); return right; } } @@ -129,8 +139,8 @@ namespace das if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, offset); + auto * right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, offset); return right; } } @@ -155,18 +165,16 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * rightC = (SimNode_CallBase *) right; - rightC->cmresEval = context.code->makeNode(rE->at, offset); - return rightC; + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, offset); + return right; } } // now, invoke with CMRES if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * rightC = (SimNode_CallBase *) right; - rightC->cmresEval = context.code->makeNode(rE->at, offset); - return rightC; + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, offset); + return right; } } // wo standard path @@ -192,8 +200,8 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, stackTop, offset); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop, offset); return right; } } @@ -201,8 +209,8 @@ namespace das if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, stackTop, offset); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop, offset); return right; } } @@ -227,18 +235,16 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * rightC = (SimNode_CallBase *) right; - rightC->cmresEval = context.code->makeNode(rE->at, stackTop, offset); - return rightC; + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop, offset); + return right; } } // now, invoke with CMRES if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * rightC = (SimNode_CallBase *) right; - rightC->cmresEval = context.code->makeNode(rE->at, stackTop, offset); - return rightC; + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop, offset); + return right; } } // wo standard path @@ -264,8 +270,8 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, stackTop); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop); return right; } } @@ -273,8 +279,8 @@ namespace das if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, stackTop); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop); return right; } } @@ -298,8 +304,8 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, stackTop); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop); return right; } } @@ -307,8 +313,8 @@ namespace das if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = context.code->makeNode(rE->at, stackTop); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = context.code->makeNode(rE->at, stackTop); return right; } } @@ -340,8 +346,8 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = lE->simulate(context); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = lE->simulate(context); return right; } } @@ -349,8 +355,8 @@ namespace das if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = lE->simulate(context); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = lE->simulate(context); return right; } } @@ -378,8 +384,8 @@ namespace das if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = lE->simulate(context); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = lE->simulate(context); return right; } } @@ -387,8 +393,8 @@ namespace das if ( rE->rtti_isInvoke() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - SimNode_CallBase * right = (SimNode_CallBase *) rE->simulate(context); - right->cmresEval = lE->simulate(context); + auto right = rE->simulate(context); + getCallBase(right)->cmresEval = lE->simulate(context); return right; } } @@ -413,14 +419,12 @@ namespace das } SimNode * Function::makeSimNode ( Context & context, const vector & ) { - { - if ( copyOnReturn || moveOnReturn ) { - return context.code->makeNodeUnrollAny(int(arguments.size()), at); - } else if ( fastCall ) { - return context.code->makeNodeUnrollAny(int(arguments.size()), at); - } else { - return context.code->makeNodeUnrollAny(int(arguments.size()), at); - } + if ( copyOnReturn || moveOnReturn ) { + return context.code->makeNodeUnrollAny(int(arguments.size()), at); + } else if ( fastCall ) { + return context.code->makeNodeUnrollAny(int(arguments.size()), at); + } else { + return context.code->makeNodeUnrollAny(int(arguments.size()), at); } } @@ -2465,8 +2469,7 @@ namespace das } else if ( returnInBlock ) { if ( returnCallCMRES ) { DAS_VERIFYF(simSubE, "internal error. can't be zero"); - SimNode_CallBase * simRet = (SimNode_CallBase *) simSubE; - simRet->cmresEval = context.code->makeNode(at,0,stackTop); + getCallBase(simSubE)->cmresEval = context.code->makeNode(at,0,stackTop); return context.code->makeNode(at, simSubE); } else if ( takeOverRightStack ) { DAS_VERIFYF(simSubE, "internal error. can't be zero"); @@ -2484,8 +2487,7 @@ namespace das } else if ( subexpr ) { if ( returnCallCMRES ) { DAS_VERIFYF(simSubE, "internal error. can't be zero"); - SimNode_CallBase * simRet = (SimNode_CallBase *) simSubE; - simRet->cmresEval = context.code->makeNode(at,0); + getCallBase(simSubE)->cmresEval = context.code->makeNode(at,0); return context.code->makeNode(at, simSubE); } else if ( returnCMRES ) { // ReturnLocalCMRes @@ -2962,13 +2964,13 @@ namespace das varExpr->variable = var; varExpr->local = local; varExpr->type = make_smart(*var->type); - SimNode_CallBase * retN = nullptr; // it has to be CALL with CMRES + SimNode * retN = nullptr; // it has to be CALL with CMRES const auto & rE = var->init; if ( rE->rtti_isCall() ) { auto cll = static_pointer_cast(rE); if ( cll->allowCmresSkip() ) { - retN = (SimNode_CallBase *) rE->simulate(context); - retN->cmresEval = varExpr->simulate(context); + retN = rE->simulate(context); + getCallBase(retN)->cmresEval = varExpr->simulate(context); } } if ( !retN ) {