VirtualBox

Changeset 44964 in vbox for trunk/src/VBox/Storage/testcase


Ignore:
Timestamp:
Mar 8, 2013 9:06:06 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
84184
Message:

Storage/testcase: A bit more work on the scripting engine

Location:
trunk/src/VBox/Storage/testcase
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/testcase/VDScript.cpp

    r44941 r44964  
    21262126                    && vdScriptTokenizerSkipIfIsPunctuatorEqual(pThis->pTokenizer, ')'))
    21272127                {
    2128                     pAstNodeWhile->pCond = pExpr;
    2129                     pAstNodeWhile->pStmt = pStmt;
     2128                    if (vdScriptTokenizerSkipIfIsPunctuatorEqual(pThis->pTokenizer, ';'))
     2129                    {
     2130                        pAstNodeWhile->pCond = pExpr;
     2131                        pAstNodeWhile->pStmt = pStmt;
     2132                    }
     2133                    else
     2134                        rc = vdScriptParserError(pThis, VERR_INVALID_PARAMETER, RT_SRC_POS, "Parser: Expected \";\", got ...\n");
    21302135                }
    21312136                else if (RT_SUCCESS(rc))
  • trunk/src/VBox/Storage/testcase/VDScriptInterp.cpp

    r44962 r44964  
    101101    /** If statement to evaluate now, the guard is on the stack. */
    102102    VDSCRIPTINTERPCTRLTYPE_IF,
    103     /** While statement. */
    104     VDSCRIPTINTERPCTRLTYPE_WHILE,
    105     /** for statement. */
    106     VDSCRIPTINTERPCTRLTYPE_FOR,
     103    /** While or for statement. */
     104    VDSCRIPTINTERPCTRLTYPE_LOOP,
    107105    /** switch statement. */
    108106    VDSCRIPTINTERPCTRLTYPE_SWITCH,
     
    113111} VDSCRIPTINTERPCTRLTYPE;
    114112/** Pointer to a control type. */
    115 typedef VDSCRIPTINTERPCTRLTYPE *PVDSCRIPINTERPCTRLTYPE;
     113typedef VDSCRIPTINTERPCTRLTYPE *PVDSCRIPTINTERPCTRLTYPE;
    116114
    117115/**
     
    289287    {
    290288        pCtrl->fEvalAst = false;
    291         pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_WHILE;
     289        pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_LOOP;
    292290        pCtrl->Ctrl.pAstNode    = &pStmt->Core;
    293291        vdScriptStackPush(&pThis->StackCtrl);
     
    308306        else if (RT_FAILURE(rc))
    309307            vdScriptStackPop(&pThis->StackCtrl); /* Cleanup the while control statement. */
     308    }
     309    else
     310        rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
     311
     312    return rc;
     313}
     314
     315/**
     316 * Pushes an if statement control entry onto the stack.
     317 *
     318 * @returns VBox status code.
     319 * @param   pThis          The interpreter context.
     320 * @param   pStmt          The if statement.
     321 */
     322static int vdScriptInterpreterPushIfCtrlEntry(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt)
     323{
     324    int rc = VINF_SUCCESS;
     325    PVDSCRIPTINTERPCTRL pCtrl = NULL;
     326
     327    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
     328    if (pCtrl)
     329    {
     330        pCtrl->fEvalAst = false;
     331        pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_IF;
     332        pCtrl->Ctrl.pAstNode    = &pStmt->Core;
     333        vdScriptStackPush(&pThis->StackCtrl);
     334
     335        rc = vdScriptInterpreterPushAstEntry(pThis, &pStmt->If.pCond->Core);
     336    }
     337    else
     338        rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
     339
     340    return rc;
     341}
     342
     343/**
     344 * Pushes a for statement control entry onto the stack.
     345 *
     346 * @returns VBox status code.
     347 * @param   pThis          The interpreter context.
     348 * @param   pStmt          The while statement.
     349 */
     350DECLINLINE(int) vdScriptInterpreterPushForCtrlEntry(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt)
     351{
     352    int rc = VINF_SUCCESS;
     353    PVDSCRIPTINTERPCTRL pCtrl = NULL;
     354
     355    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
     356    if (pCtrl)
     357    {
     358        pCtrl->fEvalAst = false;
     359        pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_LOOP;
     360        pCtrl->Ctrl.pAstNode    = &pStmt->Core;
     361        vdScriptStackPush(&pThis->StackCtrl);
     362
     363        /* Push the conditional first and the the initializer .*/
     364        rc = vdScriptInterpreterPushAstEntry(pThis, &pStmt->For.pExprCond->Core);
     365        if (RT_SUCCESS(rc))
     366        {
     367            rc = vdScriptInterpreterPushAstEntry(pThis, &pStmt->For.pExprStart->Core);
     368            if (RT_FAILURE(rc))
     369                vdScriptStackPop(&pThis->StackCtrl);
     370        }
    310371    }
    311372    else
     
    537598        }
    538599        case VDSCRIPTSTMTTYPE_IF:
     600        {
     601            rc = vdScriptInterpreterPushIfCtrlEntry(pThis, pStmt);
     602            break;
     603        }
    539604        case VDSCRIPTSTMTTYPE_SWITCH:
    540605            AssertMsgFailed(("TODO\n"));
     
    545610            break;
    546611        }
     612        case VDSCRIPTSTMTTYPE_RETURN:
     613        {
     614            /* Walk up the control stack until we reach a function cleanup entry. */
     615            PVDSCRIPTINTERPCTRL pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     616            while (   pCtrl
     617                   && (   pCtrl->fEvalAst
     618                       || pCtrl->Ctrl.enmCtrlType != VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP))
     619            {
     620                /* Cleanup up any compound statement scope. */
     621                if (   !pCtrl->fEvalAst
     622                    && pCtrl->Ctrl.enmCtrlType == VDSCRIPTINTERPCTRLTYPE_COMPOUND)
     623                    vdScriptInterpreterScopeDestroyCurr(pThis);
     624
     625                vdScriptStackPop(&pThis->StackCtrl);
     626                pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     627            }
     628            AssertMsg(VALID_PTR(pCtrl), ("Incorrect program, return outside of function\n"));
     629            break;
     630        }
    547631        case VDSCRIPTSTMTTYPE_FOR:
     632        {
     633            rc = vdScriptInterpreterPushForCtrlEntry(pThis, pStmt);
     634            break;
     635        }
    548636        case VDSCRIPTSTMTTYPE_CONTINUE:
     637        {
     638            /* Remove everything up to a loop control entry. */
     639            PVDSCRIPTINTERPCTRL pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     640            while (   pCtrl
     641                   && (   pCtrl->fEvalAst
     642                       || pCtrl->Ctrl.enmCtrlType != VDSCRIPTINTERPCTRLTYPE_LOOP))
     643            {
     644                /* Cleanup up any compound statement scope. */
     645                if (   !pCtrl->fEvalAst
     646                    && pCtrl->Ctrl.enmCtrlType == VDSCRIPTINTERPCTRLTYPE_COMPOUND)
     647                    vdScriptInterpreterScopeDestroyCurr(pThis);
     648
     649                vdScriptStackPop(&pThis->StackCtrl);
     650                pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     651            }
     652            AssertMsg(VALID_PTR(pCtrl), ("Incorrect program, continue outside of loop\n"));
     653
     654            /* Put the conditionals for while and for loops onto the control stack again. */
     655            PVDSCRIPTASTSTMT pLoopStmt = (PVDSCRIPTASTSTMT)pCtrl->Ctrl.pAstNode;
     656 
     657            AssertMsg(   pLoopStmt->enmStmtType == VDSCRIPTSTMTTYPE_WHILE
     658                      || pLoopStmt->enmStmtType == VDSCRIPTSTMTTYPE_FOR,
     659                      ("Invalid statement type, must be for or while loop\n"));
     660
     661            if (pLoopStmt->enmStmtType == VDSCRIPTSTMTTYPE_FOR)
     662                rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->For.pExprCond->Core);
     663            else if (!pLoopStmt->While.fDoWhile)
     664                rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->While.pCond->Core);
     665            break;
     666        }
    549667        case VDSCRIPTSTMTTYPE_BREAK:
    550         case VDSCRIPTSTMTTYPE_RETURN:
     668        {
     669            /* Remove everything including the loop control statement. */
     670            PVDSCRIPTINTERPCTRL pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     671            while (   pCtrl
     672                   && (   pCtrl->fEvalAst
     673                       || pCtrl->Ctrl.enmCtrlType != VDSCRIPTINTERPCTRLTYPE_LOOP))
     674            {
     675                /* Cleanup up any compound statement scope. */
     676                if (   !pCtrl->fEvalAst
     677                    && pCtrl->Ctrl.enmCtrlType == VDSCRIPTINTERPCTRLTYPE_COMPOUND)
     678                    vdScriptInterpreterScopeDestroyCurr(pThis);
     679
     680                vdScriptStackPop(&pThis->StackCtrl);
     681                pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     682            }
     683            AssertMsg(VALID_PTR(pCtrl), ("Incorrect program, break outside of loop\n"));
     684            vdScriptStackPop(&pThis->StackCtrl); /* Remove loop control statement. */
     685            break;
     686        }
    551687        case VDSCRIPTSTMTTYPE_CASE:
    552688        case VDSCRIPTSTMTTYPE_DEFAULT:
     
    751887            break;
    752888        }
    753         case VDSCRIPTINTERPCTRLTYPE_WHILE:
    754         {
    755             PVDSCRIPTASTSTMT pWhileStmt = (PVDSCRIPTASTSTMT)pCtrl->Ctrl.pAstNode;
     889        case VDSCRIPTINTERPCTRLTYPE_LOOP:
     890        {
     891            PVDSCRIPTASTSTMT pLoopStmt = (PVDSCRIPTASTSTMT)pCtrl->Ctrl.pAstNode;
    756892
    757893            /* Check whether the condition passed. */
     
    764900            {
    765901                /* Execute the loop another round. */
    766                 rc = vdScriptInterpreterPushAstEntry(pThis, &pWhileStmt->While.pCond->Core);
    767                 if (RT_SUCCESS(rc))
     902                if (pLoopStmt->enmStmtType == VDSCRIPTSTMTTYPE_WHILE)
    768903                {
    769                     rc = vdScriptInterpreterPushAstEntry(pThis, &pWhileStmt->While.pStmt->Core);
    770                     if (RT_FAILURE(rc))
    771                         vdScriptStackPop(&pThis->StackCtrl);
     904                    rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->While.pCond->Core);
     905                    if (RT_SUCCESS(rc))
     906                    {
     907                        rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->While.pStmt->Core);
     908                        if (RT_FAILURE(rc))
     909                            vdScriptStackPop(&pThis->StackCtrl);
     910                    }
    772911                }
     912                else
     913                {
     914                    AssertMsg(pLoopStmt->enmStmtType == VDSCRIPTSTMTTYPE_FOR,
     915                              ("Not a for statement\n"));
     916
     917                    rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->For.pExprCond->Core);
     918                    if (RT_SUCCESS(rc))
     919                    {
     920                        rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->For.pExpr3->Core);
     921                        if (RT_SUCCESS(rc))
     922                        {
     923                            rc = vdScriptInterpreterPushAstEntry(pThis, &pLoopStmt->For.pStmt->Core);
     924                            if (RT_FAILURE(rc))
     925                                vdScriptStackPop(&pThis->StackCtrl);
     926                        }
     927
     928                        if (RT_FAILURE(rc))
     929                            vdScriptStackPop(&pThis->StackCtrl);
     930                    }
     931                }
    773932            }
    774933            else
    775                 vdScriptStackPop(&pThis->StackCtrl); /* Remove while control statement. */
     934                vdScriptStackPop(&pThis->StackCtrl); /* Remove loop control statement. */
     935            break;
     936        }
     937        case VDSCRIPTINTERPCTRLTYPE_IF:
     938        {
     939            PVDSCRIPTASTSTMT pIfStmt = (PVDSCRIPTASTSTMT)pCtrl->Ctrl.pAstNode;
     940
     941            vdScriptStackPop(&pThis->StackCtrl); /* Remove if control statement. */
     942
     943            /* Check whether the condition passed. */
     944            VDSCRIPTARG Cond;
     945            vdScriptInterpreterPopValue(pThis, &Cond);
     946            AssertMsg(Cond.enmType == VDSCRIPTTYPE_BOOL,
     947                      ("Value on stack is not of boolean type\n"));
     948
     949            if (Cond.f)
     950            {
     951                /* Execute the true branch. */
     952                rc = vdScriptInterpreterPushAstEntry(pThis, &pIfStmt->If.pTrueStmt->Core);
     953            }
     954            else if (pIfStmt->If.pElseStmt)
     955                rc = vdScriptInterpreterPushAstEntry(pThis, &pIfStmt->If.pElseStmt->Core);
     956
    776957            break;
    777958        }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette