[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Bais/daScript/split-heap/src/simulate/simulate.cpp [Back]  [Original]

#include "daScript/misc/platform.h"

#include "daScript/simulate/simulate.h"
#include "daScript/simulate/runtime_string.h"

// this is here for the default implementation of to_out and to_err
#include 

namespace das
{
    bool SimNode::evalBool ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    float SimNode::evalFloat ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    int32_t SimNode::evalInt ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    uint32_t SimNode::evalUInt ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    int64_t SimNode::evalInt64 ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    uint64_t SimNode::evalUInt64 ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    char * SimNode::evalPtr ( Context & context ) {
        assert(0 && "we should never be here");
        return cast::to(eval(context));
    }
    
    vec4f SimNode_Swizzle::eval ( Context & context ) {
        union {
            vec4f   res;
            float   val[4];
        } R, S;
        S.res = value->eval(context);
        DAS_EXCEPTION_POINT;
        R.val[0] = S.val[fields[0]];
        R.val[1] = S.val[fields[1]];
        R.val[2] = S.val[fields[2]];
        R.val[3] = S.val[fields[3]];
        return R.res;
    }
    
    // SimNode_MakeBlock
    
    vec4f SimNode_MakeBlock::eval ( Context & context )  {
        Block block;
        block.stackOffset = context.stack.spi();
        block.argumentsOffset = argStackTop ? (context.stack.spi() + argStackTop) : 0;
        block.body = subexpr;
        return cast::from(block);
    }
    
    // SimNode_Call
    
    vec4f SimNode_Call::eval ( Context & context ) {
		vec4f * argValues = (vec4f *)(alloca(nArguments * sizeof(vec4f)));
        evalArgs(context, argValues);
        DAS_EXCEPTION_POINT;
        return context.call(fnIndex, argValues, nullptr, debug.line);
    }
    
    vec4f SimNode_CallAndCopyOrMove::eval ( Context & context ) {
        vec4f * argValues = (vec4f *)(alloca(nArguments * sizeof(vec4f)));
        evalArgs(context, argValues);
        DAS_EXCEPTION_POINT;
        auto cmres = context.stack.sp() + stackTop;
        return context.call(fnIndex, argValues, cmres, debug.line);
    }

    // SimNode_Invoke
    
    vec4f SimNode_Invoke::eval ( Context & context )  {
        vec4f * argValues = (vec4f *)(alloca(nArguments * sizeof(vec4f)));
        evalArgs(context, argValues);
        DAS_EXCEPTION_POINT;
        Block block = cast::to(argValues[0]);
        if ( nArguments>1 ) {
            return context.invoke(block, argValues + 1, nullptr);
        } else {
            return context.invoke(block, nullptr, nullptr);
        }
    }
    
    vec4f SimNode_InvokeAndCopyOrMove::eval ( Context & context )  {
        vec4f * argValues = (vec4f *)(alloca(nArguments * sizeof(vec4f)));
        evalArgs(context, argValues);
        DAS_EXCEPTION_POINT;
        Block block = cast::to(argValues[0]);
        auto cmres = context.stack.sp() + stackTop;
        if ( nArguments>1 ) {
            return context.invoke(block, argValues + 1, cmres);
        } else {
            return context.invoke(block, nullptr, cmres);
        }
    }
    
    // SimNode_Debug
    
    vec4f SimNode_Debug::eval ( Context & context ) {
        vec4f res = subexpr->eval(context);
        DAS_EXCEPTION_POINT;
        stringstream ssw;
        if ( message ) ssw evalPtr(context);
        DAS_EXCEPTION_POINT;
        auto pr = r->evalPtr(context);
        DAS_EXCEPTION_POINT;
        memcpy ( pl, pr, size );
        memset ( pr, 0, size );
        return v_zero();
    }
    
    // SimNode_Block
    
    vec4f SimNode_Block::eval ( Context & context ) {
        for ( uint32_t i = 0; i!=total && !context.stopFlags; ++i )
            list[i]->eval(context);
        return v_zero();
    }
    
    vec4f SimNode_ClosureBlock::eval ( Context & context ) {
        for ( uint32_t i = 0; i!=total && !context.stopFlags; ++i )
            list[i]->eval(context);
        if ( context.stopFlags & EvalFlags::stopForReturn ) {
            context.stopFlags &= ~EvalFlags::stopForReturn;
            return context.abiResult();
        } else {
            if ( needResult ) context.throw_error("end of block without return");
            return v_zero();
        }
    }
    
    // SimNode_Let
    
    vec4f SimNode_Let::eval ( Context & context ) {
        for ( uint32_t i = 0; i!=total && !context.stopFlags; ++i )
            list[i]->eval(context);
        DAS_EXCEPTION_POINT;
        return subexpr ? subexpr->eval(context) : v_zero();
    }
    
    // SimNode_IfThenElse
    
    vec4f SimNode_IfThenElse::eval ( Context & context ) {
        bool cmp = cond->evalBool(context);
        DAS_EXCEPTION_POINT;
        if ( cmp ) {
            return if_true->eval(context);
        } else if ( if_false ) {
            return if_false->eval(context);
        } else {
            return v_zero();
        }
    }
    
    // SimNode_While
    
    vec4f SimNode_While::eval ( Context & context ) {
        while ( cond->evalBool(context) && !context.stopFlags ) {
            body->eval(context);
        }
        context.stopFlags &= ~EvalFlags::stopForBreak;
        return v_zero();
    }
    
    // Return
    
    vec4f SimNode_Return::eval ( Context & context ) {
        if ( subexpr ) context.abiResult() = subexpr->eval(context);
        context.stopFlags |= EvalFlags::stopForReturn;
        return v_zero();
    }
    
    vec4f SimNode_ReturnAndCopy::eval ( Context & context ) {
        auto pr = subexpr->evalPtr(context);
        DAS_EXCEPTION_POINT;
        auto pl = context.abiCopyOrMoveResult();
        memcpy ( pl, pr, size);
        context.abiResult() = cast::from(pl);
        context.stopFlags |= EvalFlags::stopForReturn;
        return v_zero();
    }
    
    vec4f SimNode_ReturnAndMove::eval ( Context & context ) {
        auto pr = subexpr->evalPtr(context);
        DAS_EXCEPTION_POINT;
        auto pl = context.abiCopyOrMoveResult();
        memcpy ( pl, pr, size);
        memset ( pr, 0, size);
        context.abiResult() = cast::from(pl);
        context.stopFlags |= EvalFlags::stopForReturn;
        return v_zero();
    }

    vec4f SimNode_ReturnReference::eval ( Context & context ) {
        char * ref = subexpr->evalPtr(context);
        if ( context.stack.bottom()stackSize;
        if ( context.stack.sp()copyOrMoveResult;
        memcpy ( pl, pr, size);
        context.abiResult() = cast::from(pl);
        context.stopFlags |= EvalFlags::stopForReturn;
        return v_zero();
    }
    
    vec4f SimNode_ReturnAndMoveFromBlock::eval ( Context & context ) {
        auto pr = subexpr->evalPtr(context);
        DAS_EXCEPTION_POINT;
        auto ba = (BlockArguments *) ( context.stack.sp() + argStackTop );
        auto pl = ba->copyOrMoveResult;
        memcpy ( pl, pr, size);
        memset ( pr, 0, size);
        context.abiResult() = cast::from(pl);
        context.stopFlags |= EvalFlags::stopForReturn;
        return v_zero();
    }
    
    vec4f SimNode_ReturnReferenceFromBlock::eval ( Context & context ) {
        char * ref = subexpr->evalPtr(context);
        if ( context.stack.bottom()copyOrMoveResult = (char *) cmres;
        }
        when(block.body);
        if ( ba ) {
            *ba = saveArguments;
        }
		stack.pop(watermark);
        return result;
    }
#ifdef _MSC_VER
#pragma warning(pop)
#endif

    vec4f Context::callEx(int fnIndex, vec4f *args, void * cmres, int line, function && when) {
        assert(fnIndex>=0 && fnIndexarguments =     args;
        pp->copyOrMoveResult = (char *)cmres;
#if DAS_ENABLE_STACK_WALK
        pp->info =          fn.debug;
        pp->line =          line;
#endif
        // CALL
        when(fn.code);
        stopFlags &= ~(EvalFlags::stopForReturn | EvalFlags::stopForBreak);
        // POP
		stack.pop(watermark);
        return result;
    }

    
    void Context::runInitScript ( void ) {
        for ( int i=0; i!=totalVariables && !stopFlags; ++i ) {
            auto & pv = globalVariables[i];
            if ( pv.init ) {
                pv.init->eval(*this);
            } else {
                memset ( cast::to(pv.value), 0, pv.size );
            }
        }
    }
    
    int Context::findFunction ( const char * name ) const {
        for ( int fni = 0; fni != totalFunctions; ++fni ) {
            if ( strcmp(functions[fni].name, name)==0 ) {
                return fni;
            }
        }
        return -1;
    }
    
    int Context::findVariable ( const char * name ) const {
        for ( int vni = 0; vni != totalVariables; ++vni ) {
            if ( strcmp(globalVariables[vni].name, name)==0 ) {
                return vni;
            }
        }
        return -1;
    }
    
    void Context::stackWalk() {
        auto str = getStackWalk();
        to_out(str.c_str());
    }
    
    string Context::getStackWalk( bool args ) {
        stringstream ssw;
    #if DAS_ENABLE_STACK_WALK
        ssw 

Web Proxy Viewer  |  New URL  |  Original Page