VirtualBox

Changeset 44901 in vbox for trunk


Ignore:
Timestamp:
Mar 1, 2013 11:46:09 PM (12 years ago)
Author:
vboxsync
Message:

Storage/VDScript: Interpreter updates

Location:
trunk/src/VBox/Storage/testcase
Files:
1 added
4 edited

Legend:

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

    r44855 r44901  
    181181    PVDSCRIPTTOKEN pTokenNext;
    182182} VDTOKENIZER;
    183 
    184 /**
    185  * Script function which can be called.
    186  */
    187 typedef struct VDSCRIPTFN
    188 {
    189     /** String space core. */
    190     RTSTRSPACECORE               Core;
    191     /** Flag whether function is defined in the source or was
    192      * registered from the outside. */
    193     bool                         fExternal;
    194     /** Flag dependent data. */
    195     union
    196     {
    197         /** Data for functions defined in the source. */
    198         struct
    199         {
    200             /** Pointer to the AST defining the function. */
    201             PVDSCRIPTASTFN       pAstFn;
    202         } Internal;
    203         /** Data for external defined functions. */
    204         struct
    205         {
    206             /** Callback function. */
    207             PFNVDSCRIPTCALLBACK  pfnCallback;
    208             /** Opaque user data. */
    209             void                *pvUser;
    210         } External;
    211     } Type;
    212     /** Return type of the function. */
    213     VDSCRIPTTYPE                 enmTypeRetn;
    214     /** Number of arguments the function takes. */
    215     unsigned                     cArgs;
    216     /** Variable sized array of argument types. */
    217     VDSCRIPTTYPE                 aArgTypes[1];
    218 } VDSCRIPTFN;
    219 typedef VDSCRIPTFN *PVDSCRIPTFN;
    220183
    221184/**
     
    26612624        }
    26622625
    2663         pFn = (PVDSCRIPTFN)RTMemAllocZ(RT_OFFSETOF(VDSCRIPTFN, aArgTypes[paCallbacks->cArgs]));
     2626        pFn = (PVDSCRIPTFN)RTMemAllocZ(RT_OFFSETOF(VDSCRIPTFN, aenmArgTypes[paCallbacks->cArgs]));
    26642627        if (!pFn)
    26652628        {
     
    26782641
    26792642        for (unsigned i = 0; i < paCallbacks->cArgs; i++)
    2680             pFn->aArgTypes[i] = paCallbacks->paArgs[i];
     2643            pFn->aenmArgTypes[i] = paCallbacks->paArgs[i];
    26812644
    26822645        RTStrSpaceInsert(&pThis->hStrSpaceFn, &pFn->Core);
  • trunk/src/VBox/Storage/testcase/VDScriptAst.h

    r44855 r44901  
    5454    /** Expression node. */
    5555    VDSCRIPTASTCLASS_EXPRESSION,
    56     /** @todo: Add if ... else, loops, ... */
    5756    /** 32bit blowup. */
    5857    VDSCRIPTASTCLASS_32BIT_HACK = 0x7fffffff
  • trunk/src/VBox/Storage/testcase/VDScriptInternal.h

    r44891 r44901  
    2222
    2323#include "VDScript.h"
     24
     25/**
     26 * Script function which can be called.
     27 */
     28typedef struct VDSCRIPTFN
     29{
     30    /** String space core. */
     31    RTSTRSPACECORE               Core;
     32    /** Flag whether function is defined in the source or was
     33     * registered from the outside. */
     34    bool                         fExternal;
     35    /** Flag dependent data. */
     36    union
     37    {
     38        /** Data for functions defined in the source. */
     39        struct
     40        {
     41            /** Pointer to the AST defining the function. */
     42            PVDSCRIPTASTFN       pAstFn;
     43        } Internal;
     44        /** Data for external defined functions. */
     45        struct
     46        {
     47            /** Callback function. */
     48            PFNVDSCRIPTCALLBACK  pfnCallback;
     49            /** Opaque user data. */
     50            void                *pvUser;
     51        } External;
     52    } Type;
     53    /** Return type of the function. */
     54    VDSCRIPTTYPE                 enmTypeRetn;
     55    /** Number of arguments the function takes. */
     56    unsigned                     cArgs;
     57    /** Variable sized array of argument types. */
     58    VDSCRIPTTYPE                 aenmArgTypes[1];
     59} VDSCRIPTFN;
     60/** Pointer to a script function registration structure. */
     61typedef VDSCRIPTFN *PVDSCRIPTFN;
    2462
    2563/** Pointer to a tokenize state. */
     
    5694 * @returns VBox status code.
    5795 * @param   pThis    The script context.
    58  * @param   pAstFn   The function AST to interpret.
     96 * @param   pszFn    The function name to interprete.
    5997 * @param   paArgs   Arguments to pass to the function.
    6098 * @param   cArgs    Number of arguments.
    6199 * @param   pRet     Where to store the return value on success.
     100 *
     101 * @note: The AST is not modified in any way during the interpretation process.
    62102 */
    63 DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTFN pAstFn,
     103DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, const char *pszFn,
    64104                                      PVDSCRIPTARG paArgs, unsigned cArgs,
    65105                                      PVDSCRIPTARG pRet);
  • trunk/src/VBox/Storage/testcase/VDScriptInterp.cpp

    r44891 r44901  
    2424
    2525#include "VDScriptAst.h"
     26#include "VDScriptStack.h"
    2627#include "VDScriptInternal.h"
     28
     29/**
     30 * Interpreter variable.
     31 */
     32typedef struct VDSCRIPTINTERPVAR
     33{
     34    /** String space core. */
     35    RTSTRSPACECORE              Core;
     36    /** Value. */
     37    VDSCRIPTARG                 Value;
     38} VDSCRIPTINTERPVAR;
     39/** Pointer to an interpreter variable. */
     40typedef VDSCRIPTINTERPVAR *PVDSCRIPTINTERPVAR;
    2741
    2842/**
     
    3347    /** Pointer to the enclosing scope if available. */
    3448    struct VDSCRIPTINTERPSCOPE *pParent;
    35     /** String space of accessible variables. */
     49    /** String space of declared variables in this scope. */
    3650    RTSTRSPACE                  hStrSpaceVar;
    3751} VDSCRIPTINTERPSCOPE;
     
    5973typedef struct VDSCRIPTINTERPCTX
    6074{
     75    /** Pointer to the script context. */
     76    PVDSCRIPTCTXINT             pScriptCtx;
    6177    /** Current function call entry. */
    6278    PVDSCRIPTINTERPFNCALL       pFnCallCurr;
    6379    /** Stack of calculated values. */
    64     PVDSCRIPTARG                pStackVal;
    65     /** Number of values on the stack. */
    66     unsigned                    cValuesOnStack;
    67     /** Maximum number of values the stack can hold currently. */
    68     unsigned                    cValuesOnStackMax;
    69     /** Stack of executed AST nodes. */
    70     PVDSCRIPTASTCORE           *ppStackAstCompute;
    71     /** Number of AST nodes on the stack. */
    72     unsigned                    cAstNodesOnStack;
    73     /** Maximum number of AST nodes the stack can hold. */
    74     unsigned                    cAstNodesOnStackMax;
     80    VDSCRIPTSTACK               StackValues;
     81    /** Evaluation control stack. */
     82    VDSCRIPTSTACK               StackCtrl;
    7583} VDSCRIPTINTERPCTX;
    7684/** Pointer to an interpreter context. */
     
    7886
    7987/**
     88 * Interpreter control type.
     89 */
     90typedef enum VDSCRIPTINTERPCTRLTYPE
     91{
     92    VDSCRIPTINTERPCTRLTYPE_INVALID = 0,
     93    /** Function call to evaluate now, all values are computed
     94     * and are stored on the value stack.
     95     */
     96    VDSCRIPTINTERPCTRLTYPE_FN_CALL,
     97    /** Cleanup the function call, deleting the scope and restoring the previous one. */
     98    VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP,
     99    /** If statement to evaluate now, the guard is on the stack. */
     100    VDSCRIPTINTERPCTRLTYPE_IF,
     101    VDSCRIPTINTERPCTRLTYPE_32BIT_HACK = 0x7fffffff
     102} VDSCRIPTINTERPCTRLTYPE;
     103/** Pointer to a control type. */
     104typedef VDSCRIPTINTERPCTRLTYPE *PVDSCRIPINTERPCTRLTYPE;
     105
     106/**
     107 * Interpreter stack control entry.
     108 */
     109typedef struct VDSCRIPTINTERPCTRL
     110{
     111    /** Flag whether this entry points to an AST node to evaluate. */
     112    bool                           fEvalAst;
     113    /** Flag dependent data. */
     114    union
     115    {
     116        /** Pointer to the AST node to interprete. */
     117        PVDSCRIPTASTCORE           pAstNode;
     118        /** Interpreter control structure. */
     119        struct
     120        {
     121            /** Type of control. */
     122            VDSCRIPTINTERPCTRLTYPE enmCtrlType;
     123            /** Function call data. */
     124            struct
     125            {
     126                /** Function to call. */
     127                PVDSCRIPTASTFN     pAstFn;
     128            } FnCall;
     129        } Ctrl;
     130    };
     131} VDSCRIPTINTERPCTRL;
     132/** Pointer to an exec stack control entry. */
     133typedef VDSCRIPTINTERPCTRL *PVDSCRIPTINTERPCTRL;
     134
     135/**
    80136 * Record an error while interpreting.
    81137 *
    82138 * @returns VBox status code passed.
    83  * @param   pThis      The script context.
     139 * @param   pThis      The interpreter context.
    84140 * @param   rc         The status code to record.
    85141 * @param   RT_SRC_POS Position in the source code.
    86142 * @param   pszFmt     Format string.
    87143 */
    88 static int vdScriptInterpreterError(PVDSCRIPTCTXINT pThis, int rc, RT_SRC_POS_DECL, const char *pszFmt, ...)
    89 {
    90     return rc;
    91 }
    92 
    93 DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTFN pAstFn,
     144static int vdScriptInterpreterError(PVDSCRIPTINTERPCTX pThis, int rc, RT_SRC_POS_DECL, const char *pszFmt, ...)
     145{
     146    return rc;
     147}
     148
     149/**
     150 * Pops the topmost value from the value stack.
     151 *
     152 * @returns nothing.
     153 * @param   pThis      The interpreter context.
     154 * @param   pVal       Where to store the value.
     155 */
     156DECLINLINE(void) vdScriptInterpreterPopValue(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTARG pVal)
     157{
     158    PVDSCRIPTARG pValStack = (PVDSCRIPTARG)vdScriptStackGetUsed(&pThis->StackValues);
     159    AssertPtrReturnVoid(pValStack);
     160
     161    *pVal = *pValStack;
     162    vdScriptStackPop(&pThis->StackValues);
     163}
     164
     165/**
     166 * Pushes a given value onto the value stack.
     167 */
     168DECLINLINE(int) vdScriptInterpreterPushValue(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTARG pVal)
     169{
     170    PVDSCRIPTARG pValStack = (PVDSCRIPTARG)vdScriptStackGetUsed(&pThis->StackValues);
     171    if (!pValStack)
     172        return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory pushing a value on the value stack");
     173
     174    *pValStack = *pVal;
     175    vdScriptStackPush(&pThis->StackValues);
     176    return VINF_SUCCESS;
     177}
     178
     179/**
     180 * Pushes a control entry without additional data onto the stack.
     181 *
     182 * @returns VBox status code.
     183 * @param   pThis          The interpreter context.
     184 * @param   enmCtrlType    The control entry type.
     185 */
     186DECLINLINE(int) vdScriptInterpreterPushNonDataCtrlEntry(PVDSCRIPTINTERPCTX pThis,
     187                                                        VDSCRIPTINTERPCTRLTYPE enmCtrlType)
     188{
     189    PVDSCRIPTINTERPCTRL pCtrl = NULL;
     190
     191    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
     192    if (pCtrl)
     193    {
     194        pCtrl->fEvalAst = false;
     195        pCtrl->Ctrl.enmCtrlType = enmCtrlType;
     196        vdScriptStackPush(&pThis->StackCtrl);
     197        return VINF_SUCCESS;
     198    }
     199
     200    return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
     201}
     202
     203/**
     204 * Pushes an AST node onto the control stack.
     205 *
     206 * @returns VBox status code.
     207 * @param   pThis          The interpreter context.
     208 * @param   enmCtrlType    The control entry type.
     209 */
     210DECLINLINE(int) vdScriptInterpreterPushAstEntry(PVDSCRIPTINTERPCTX pThis,
     211                                                PVDSCRIPTASTCORE pAstNode)
     212{
     213    PVDSCRIPTINTERPCTRL pCtrl = NULL;
     214
     215    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
     216
     217    if (pCtrl)
     218    {
     219        pCtrl->fEvalAst = true;
     220        pCtrl->pAstNode = pAstNode;
     221        vdScriptStackPush(&pThis->StackCtrl);
     222        return VINF_SUCCESS;
     223    }
     224
     225    return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
     226}
     227
     228/**
     229 * Evaluate a statement.
     230 *
     231 * @returns VBox status code.
     232 * @param   pThis      The interpreter context.
     233 * @param   pStmt      The statement to evaluate.
     234 */
     235static int vdScriptInterpreterEvaluateStatement(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt)
     236{
     237    int rc = VERR_NOT_IMPLEMENTED;
     238    return rc;
     239}
     240
     241/**
     242 * Evaluate an expression.
     243 *
     244 * @returns VBox status code.
     245 * @param   pThis      The interpreter context.
     246 * @param   pExpr      The expression to evaluate.
     247 */
     248static int vdScriptInterpreterEvaluateExpression(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTEXPR pExpr)
     249{
     250    int rc = VERR_NOT_IMPLEMENTED;
     251    return rc;
     252}
     253
     254/**
     255 * Evaluates the given AST node.
     256 *
     257 * @returns VBox statuse code.
     258 * @param   pThis      The interpreter context.
     259 * @param   pAstNode   The AST node to interpret.
     260 */
     261static int vdScriptInterpreterEvaluateAst(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTCORE pAstNode)
     262{
     263    int rc = VERR_NOT_IMPLEMENTED;
     264
     265    switch (pAstNode->enmClass)
     266    {
     267        case VDSCRIPTASTCLASS_DECLARATION:
     268        {
     269            break;
     270        }
     271        case VDSCRIPTASTCLASS_IDENTIFIER:
     272        {
     273            /*
     274             * Identifiers are pushed only to the stack as an identifier for a variable.
     275             * Look it up and push the value onto the value stack.
     276             */
     277            PVDSCRIPTASTIDE pIde = (PVDSCRIPTASTIDE)pAstNode;
     278            PVDSCRIPTINTERPVAR pVar = (PVDSCRIPTINTERPVAR)RTStrSpaceGet(&pThis->pFnCallCurr->pScopeCurr->hStrSpaceVar, pIde->aszIde);
     279
     280            AssertPtrReturn(pVar, VERR_IPE_UNINITIALIZED_STATUS);
     281            rc = vdScriptInterpreterPushValue(pThis, &pVar->Value);
     282            break;
     283        }
     284        case VDSCRIPTASTCLASS_STATEMENT:
     285        {
     286            rc = vdScriptInterpreterEvaluateStatement(pThis, (PVDSCRIPTASTSTMT)pAstNode);
     287            break;
     288        }
     289        case VDSCRIPTASTCLASS_EXPRESSION:
     290        {
     291            rc = vdScriptInterpreterEvaluateExpression(pThis, (PVDSCRIPTASTEXPR)pAstNode);
     292            break;
     293        }
     294        /* These should never ever appear here. */
     295        case VDSCRIPTASTCLASS_FUNCTION:
     296        case VDSCRIPTASTCLASS_FUNCTIONARG:
     297        case VDSCRIPTASTCLASS_INVALID:
     298        default:
     299            AssertMsgFailed(("Invalid AST node class: %d\n", pAstNode->enmClass));
     300    }
     301
     302    return rc;
     303}
     304
     305/**
     306 * Destroy variable string space callback.
     307 */
     308static DECLCALLBACK(int) vdScriptInterpreterVarSpaceDestroy(PRTSTRSPACECORE pStr, void *pvUser)
     309{
     310    RTMemFree(pStr);
     311    return VINF_SUCCESS;
     312}
     313
     314/**
     315 * Evaluate a function call.
     316 *
     317 * @returns VBox status code.
     318 * @param   pThis      The interpreter context.
     319 * @param
     320 */
     321static int vdScriptInterpreterFnCall(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTFN pAstFn)
     322{
     323    int rc = VINF_SUCCESS;
     324
     325    /* Add function call cleanup marker on the stack first. */
     326    rc = vdScriptInterpreterPushNonDataCtrlEntry(pThis, VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP);
     327    if (RT_SUCCESS(rc))
     328    {
     329        /* Create function call frame and set it up. */
     330        PVDSCRIPTINTERPFNCALL pFnCall = (PVDSCRIPTINTERPFNCALL)RTMemAllocZ(sizeof(VDSCRIPTINTERPFNCALL));
     331        if (pFnCall)
     332        {
     333            pFnCall->pCaller = pThis->pFnCallCurr;
     334            pFnCall->ScopeRoot.pParent = NULL;
     335            pFnCall->ScopeRoot.hStrSpaceVar = NULL;
     336
     337            /* Add the variables, remember order. The first variable in the argument has the value at the top of the value stack. */
     338            PVDSCRIPTASTFNARG pArg = RTListGetFirst(&pAstFn->ListArgs, VDSCRIPTASTFNARG, Core.ListNode);
     339            for (unsigned i = 0; i < pAstFn->cArgs; i++)
     340            {
     341                PVDSCRIPTINTERPVAR pVar = (PVDSCRIPTINTERPVAR)RTMemAllocZ(sizeof(VDSCRIPTINTERPVAR));
     342                if (pVar)
     343                {
     344                    pVar->Core.pszString = pArg->pArgIde->aszIde;
     345                    pVar->Core.cchString = pArg->pArgIde->cchIde;
     346                    vdScriptInterpreterPopValue(pThis, &pVar->Value);
     347                    bool fInserted = RTStrSpaceInsert(&pFnCall->ScopeRoot.hStrSpaceVar, &pVar->Core);
     348                    Assert(fInserted);
     349                }
     350                else
     351                {
     352                    rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a variable");
     353                    break;
     354                }
     355                pArg = RTListGetNext(&pAstFn->ListArgs, pArg, VDSCRIPTASTFNARG, Core.ListNode);
     356            }
     357
     358            if (RT_SUCCESS(rc))
     359            {
     360                /*
     361                 * Push compount statement on the control stack and make the newly created
     362                 * call frame the current one.
     363                 */
     364                rc = vdScriptInterpreterPushAstEntry(pThis, &pAstFn->pCompoundStmts->Core);
     365                if (RT_SUCCESS(rc))
     366                    pThis->pFnCallCurr = pFnCall;
     367            }
     368
     369            if (RT_FAILURE(rc))
     370            {
     371                RTStrSpaceDestroy(&pFnCall->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL);
     372                RTMemFree(pFnCall);
     373            }
     374        }
     375        else
     376            rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a call frame");
     377    }
     378
     379    return rc;
     380}
     381
     382/**
     383 * The interpreter evaluation core loop.
     384 *
     385 * @returns VBox status code.
     386 * @param   pThis      The interpreter context.
     387 */
     388static int vdScriptInterpreterEvaluate(PVDSCRIPTINTERPCTX pThis)
     389{
     390    int rc = VINF_SUCCESS;
     391    PVDSCRIPTINTERPCTRL pCtrl = NULL;
     392
     393    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     394    while (pCtrl)
     395    {
     396        if (pCtrl->fEvalAst)
     397        {
     398            PVDSCRIPTASTCORE pAstNode = pCtrl->pAstNode;
     399            vdScriptStackPop(&pThis->StackCtrl);
     400
     401            rc = vdScriptInterpreterEvaluateAst(pThis, pAstNode);
     402        }
     403        else
     404        {
     405            switch (pCtrl->Ctrl.enmCtrlType)
     406            {
     407                case VDSCRIPTINTERPCTRLTYPE_FN_CALL:
     408                {
     409                    PVDSCRIPTASTFN pAstFn = pCtrl->Ctrl.FnCall.pAstFn;
     410
     411                    vdScriptStackPop(&pThis->StackCtrl);
     412                    rc = vdScriptInterpreterFnCall(pThis, pAstFn);
     413                    break;
     414                }
     415                case VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP:
     416                {
     417                    vdScriptStackPop(&pThis->StackCtrl);
     418
     419                    /* Delete function call entry. */
     420                    AssertPtr(pThis->pFnCallCurr);
     421                    PVDSCRIPTINTERPFNCALL pFnCallFree = pThis->pFnCallCurr;
     422
     423                    pThis->pFnCallCurr = pFnCallFree->pCaller;
     424                    Assert(pFnCallFree->pScopeCurr == &pFnCallFree->ScopeRoot);
     425                    RTStrSpaceDestroy(&pFnCallFree->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL);
     426                    RTMemFree(pFnCallFree);
     427                    break;
     428                }
     429                default:
     430                    AssertMsgFailed(("Invalid evaluation control type on the stack: %d\n",
     431                                     pCtrl->Ctrl.enmCtrlType));
     432            }
     433        }
     434        pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl);
     435    }
     436
     437    return rc;
     438}
     439
     440DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, const char *pszFn,
    94441                                      PVDSCRIPTARG paArgs, unsigned cArgs,
    95442                                      PVDSCRIPTARG pRet)
    96443{
    97     return VERR_NOT_IMPLEMENTED;
    98 }
     444    int rc = VINF_SUCCESS;
     445    VDSCRIPTINTERPCTX InterpCtx;
     446    PVDSCRIPTFN pFn = NULL;
     447
     448    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     449    AssertPtrReturn(pszFn, VERR_INVALID_POINTER);
     450    AssertReturn(   (!cArgs && !paArgs)
     451                 || (cArgs && paArgs), VERR_INVALID_PARAMETER);
     452
     453    InterpCtx.pScriptCtx  = pThis;
     454    InterpCtx.pFnCallCurr = NULL;
     455    vdScriptStackInit(&InterpCtx.StackValues, sizeof(VDSCRIPTARG));
     456    vdScriptStackInit(&InterpCtx.StackCtrl, sizeof(VDSCRIPTINTERPCTRL));
     457
     458    pFn = (PVDSCRIPTFN)RTStrSpaceGet(&pThis->hStrSpaceFn, pszFn);
     459    if (pFn)
     460    {
     461        if (cArgs == pFn->cArgs)
     462        {
     463            /* Push the arguments onto the stack. */
     464            /** @todo: Check expected and given argument types. */
     465            for (unsigned i = 0; i < cArgs; i++)
     466            {
     467                PVDSCRIPTARG pArg = (PVDSCRIPTARG)vdScriptStackGetUnused(&InterpCtx.StackValues);
     468                *pArg = paArgs[i];
     469                vdScriptStackPush(&InterpCtx.StackValues);
     470            }
     471
     472            if (RT_SUCCESS(rc))
     473            {
     474                /* Push the AST onto the stack. */
     475                PVDSCRIPTINTERPCTRL pCtrlFn = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&InterpCtx.StackCtrl);
     476                pCtrlFn->fEvalAst = false;
     477                pCtrlFn->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_FN_CALL;
     478                pCtrlFn->Ctrl.FnCall.pAstFn = pFn->Type.Internal.pAstFn;
     479                vdScriptStackPush(&InterpCtx.StackCtrl);
     480
     481                /* Run the interpreter. */
     482                rc = vdScriptInterpreterEvaluate(&InterpCtx);
     483            }
     484        }
     485        else
     486            rc = vdScriptInterpreterError(&InterpCtx, VERR_INVALID_PARAMETER, RT_SRC_POS, "Invalid number of parameters, expected %d got %d", pFn->cArgs, cArgs);
     487    }
     488    else
     489        rc = vdScriptInterpreterError(&InterpCtx, VERR_NOT_FOUND, RT_SRC_POS, "Function with identifier \"%s\" not found", pszFn);
     490
     491
     492    return rc;
     493}
Note: See TracChangeset for help on using the changeset viewer.

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