void vboxDispCmLog(LPCSTR pszMsg) { PVBOXDISPCM_SESSION pSession = &g_pVBoxCmMgr.Session; EnterCriticalSection(&pSession->CritSect); /* use any context for identifying the kernel CmSession. We're using the first one */ PVBOXWDDMDISP_CONTEXT pContext = RTListGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode); Assert(pContext); if (pContext) { PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice; Assert(pDevice); vboxVDbgPrint(("%s", pszMsg)); } LeaveCriticalSection(&pSession->CritSect); }
/** * Pushes a compound statement control entry onto the stack. * * @returns VBox status code. * @param pThis The interpreter context. * @param pStmtFirst The first statement of the compound statement */ DECLINLINE(int) vdScriptInterpreterPushCompoundCtrlEntry(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt) { PVDSCRIPTINTERPCTRL pCtrl = NULL; pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl); if (pCtrl) { pCtrl->fEvalAst = false; pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_COMPOUND; pCtrl->Ctrl.Compound.pStmtCompound = pStmt; pCtrl->Ctrl.Compound.pStmtCurr = RTListGetFirst(&pStmt->Compound.ListStmts, VDSCRIPTASTSTMT, Core.ListNode); vdScriptStackPush(&pThis->StackCtrl); return VINF_SUCCESS; } return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack"); }
static HRESULT vboxDispCmSessionCmdQueryData(PVBOXDISPCM_SESSION pSession, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd) { HRESULT hr = S_OK; D3DDDICB_ESCAPE DdiEscape; DdiEscape.Flags.Value = 0; DdiEscape.pPrivateDriverData = pCmd; DdiEscape.PrivateDriverDataSize = cbCmd; pCmd->EscapeHdr.escapeCode = VBOXESC_GETVBOXVIDEOCMCMD; /* lock to ensure the context is not destroyed */ EnterCriticalSection(&pSession->CritSect); /* use any context for identifying the kernel CmSession. We're using the first one */ PVBOXWDDMDISP_CONTEXT pContext = RTListGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode); if (pContext) { PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice; DdiEscape.hDevice = pDevice->hDevice; DdiEscape.hContext = pContext->ContextInfo.hContext; Assert (DdiEscape.hContext); Assert (DdiEscape.hDevice); hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape); LeaveCriticalSection(&pSession->CritSect); Assert(hr == S_OK); if (hr == S_OK) { if (!pCmd->Hdr.cbCmdsReturned && !pCmd->Hdr.cbRemainingFirstCmd) hr = S_FALSE; } else { vboxVDbgPrint(("DispD3D: vboxDispCmSessionCmdQueryData, pfnEscapeCb failed hr (0x%x)\n", hr)); exit(1); } } else { LeaveCriticalSection(&pSession->CritSect); hr = S_FALSE; } return hr; }
/** * Free a given statement AST node and put everything on the given to free list. * * @returns nothing. * @param pList The free list to append everything to. * @param pAstNode The statement node to free. */ static void vdScriptAstNodeStatmentPutOnFreeList(PRTLISTANCHOR pList, PVDSCRIPTASTCORE pAstNode) { AssertMsgReturnVoid(pAstNode->enmClass == VDSCRIPTASTCLASS_STATEMENT, ("Given AST node is not a statement\n")); PVDSCRIPTASTSTMT pStmt = (PVDSCRIPTASTSTMT)pAstNode; switch (pStmt->enmStmtType) { case VDSCRIPTSTMTTYPE_COMPOUND: { /* Put all declarations on the to free list. */ while (!RTListIsEmpty(&pStmt->Compound.ListDecls)) { PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListDecls, VDSCRIPTASTCORE, ListNode); RTListNodeRemove(&pNode->ListNode); RTListAppend(pList, &pNode->ListNode); } /* Put all statements on the to free list. */ while (!RTListIsEmpty(&pStmt->Compound.ListStmts)) { PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListDecls, VDSCRIPTASTCORE, ListNode); RTListNodeRemove(&pNode->ListNode); RTListAppend(pList, &pNode->ListNode); } break; } case VDSCRIPTSTMTTYPE_EXPRESSION: { RTListAppend(pList, &pStmt->pExpr->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_IF: { RTListAppend(pList, &pStmt->If.pCond->Core.ListNode); RTListAppend(pList, &pStmt->If.pTrueStmt->Core.ListNode); if (pStmt->If.pElseStmt) RTListAppend(pList, &pStmt->If.pElseStmt->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_SWITCH: { RTListAppend(pList, &pStmt->Switch.pCond->Core.ListNode); RTListAppend(pList, &pStmt->Switch.pStmt->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_WHILE: { RTListAppend(pList, &pStmt->While.pCond->Core.ListNode); RTListAppend(pList, &pStmt->While.pStmt->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_FOR: { RTListAppend(pList, &pStmt->For.pExprStart->Core.ListNode); RTListAppend(pList, &pStmt->For.pExprCond->Core.ListNode); RTListAppend(pList, &pStmt->For.pExpr3->Core.ListNode); RTListAppend(pList, &pStmt->For.pStmt->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_RETURN: { if (pStmt->pExpr) RTListAppend(pList, &pStmt->pExpr->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_CASE: { RTListAppend(pList, &pStmt->Case.pExpr->Core.ListNode); RTListAppend(pList, &pStmt->Case.pStmt->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_DEFAULT: { RTListAppend(pList, &pStmt->Case.pStmt->Core.ListNode); break; } case VDSCRIPTSTMTTYPE_CONTINUE: case VDSCRIPTSTMTTYPE_BREAK: break; case VDSCRIPTSTMTTYPE_INVALID: default: AssertMsgFailedReturnVoid(("Invalid AST node statement type %d\n", pStmt->enmStmtType)); } }
DECLHIDDEN(void) vdScriptAstNodeFree(PVDSCRIPTASTCORE pAstNode) { RTLISTANCHOR ListFree; /* * The node is not allowed to be part of a list because we need it * for the nodes to free list. */ Assert(RTListIsEmpty(&pAstNode->ListNode)); RTListInit(&ListFree); RTListAppend(&ListFree, &pAstNode->ListNode); do { pAstNode = RTListGetFirst(&ListFree, VDSCRIPTASTCORE, ListNode); RTListNodeRemove(&pAstNode->ListNode); switch (pAstNode->enmClass) { case VDSCRIPTASTCLASS_FUNCTION: { PVDSCRIPTASTFN pFn = (PVDSCRIPTASTFN)pAstNode; if (pFn->pRetType) RTListAppend(&ListFree, &pFn->pRetType->Core.ListNode); if (pFn->pFnIde) RTListAppend(&ListFree, &pFn->pFnIde->Core.ListNode); /* Put argument list on the to free list. */ while (!RTListIsEmpty(&pFn->ListArgs)) { PVDSCRIPTASTCORE pArg = RTListGetFirst(&pFn->ListArgs, VDSCRIPTASTCORE, ListNode); RTListNodeRemove(&pArg->ListNode); RTListAppend(&ListFree, &pArg->ListNode); } /* Put compound statement onto the list. */ RTListAppend(&ListFree, &pFn->pCompoundStmts->Core.ListNode); break; } case VDSCRIPTASTCLASS_FUNCTIONARG: { PVDSCRIPTASTFNARG pAstNodeArg = (PVDSCRIPTASTFNARG)pAstNode; if (pAstNodeArg->pType) RTListAppend(&ListFree, &pAstNodeArg->pType->Core.ListNode); if (pAstNodeArg->pArgIde) RTListAppend(&ListFree, &pAstNodeArg->pArgIde->Core.ListNode); break; } case VDSCRIPTASTCLASS_IDENTIFIER: break; case VDSCRIPTASTCLASS_DECLARATION: break; case VDSCRIPTASTCLASS_STATEMENT: { vdScriptAstNodeStatmentPutOnFreeList(&ListFree, pAstNode); break; } case VDSCRIPTASTCLASS_EXPRESSION: { vdScriptAStNodeExpressionPutOnFreeList(&ListFree, pAstNode); break; } case VDSCRIPTASTCLASS_INVALID: default: AssertMsgFailedReturnVoid(("Invalid AST node class given %d\n", pAstNode->enmClass)); } RTMemFree(pAstNode); } while (!RTListIsEmpty(&ListFree)); }
/** * Evaluate a function call. * * @returns VBox status code. * @param pThis The interpreter context. * @param pFn The function execute. */ static int vdScriptInterpreterFnCall(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTFN pFn) { int rc = VINF_SUCCESS; if (!pFn->fExternal) { PVDSCRIPTASTFN pAstFn = pFn->Type.Internal.pAstFn; /* Add function call cleanup marker on the stack first. */ rc = vdScriptInterpreterPushNonDataCtrlEntry(pThis, VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP); if (RT_SUCCESS(rc)) { /* Create function call frame and set it up. */ PVDSCRIPTINTERPFNCALL pFnCall = (PVDSCRIPTINTERPFNCALL)RTMemAllocZ(sizeof(VDSCRIPTINTERPFNCALL)); if (pFnCall) { pFnCall->pCaller = pThis->pFnCallCurr; pFnCall->ScopeRoot.pParent = NULL; pFnCall->ScopeRoot.hStrSpaceVar = NULL; pFnCall->pScopeCurr = &pFnCall->ScopeRoot; /* Add the variables, remember order. The first variable in the argument has the value at the top of the value stack. */ PVDSCRIPTASTFNARG pArg = RTListGetFirst(&pAstFn->ListArgs, VDSCRIPTASTFNARG, Core.ListNode); for (unsigned i = 0; i < pAstFn->cArgs; i++) { PVDSCRIPTINTERPVAR pVar = (PVDSCRIPTINTERPVAR)RTMemAllocZ(sizeof(VDSCRIPTINTERPVAR)); if (pVar) { pVar->Core.pszString = pArg->pArgIde->aszIde; pVar->Core.cchString = pArg->pArgIde->cchIde; vdScriptInterpreterPopValue(pThis, &pVar->Value); bool fInserted = RTStrSpaceInsert(&pFnCall->ScopeRoot.hStrSpaceVar, &pVar->Core); Assert(fInserted); } else { rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a variable"); break; } pArg = RTListGetNext(&pAstFn->ListArgs, pArg, VDSCRIPTASTFNARG, Core.ListNode); } if (RT_SUCCESS(rc)) { /* * Push compount statement on the control stack and make the newly created * call frame the current one. */ rc = vdScriptInterpreterPushAstEntry(pThis, &pAstFn->pCompoundStmts->Core); if (RT_SUCCESS(rc)) pThis->pFnCallCurr = pFnCall; } if (RT_FAILURE(rc)) { RTStrSpaceDestroy(&pFnCall->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL); RTMemFree(pFnCall); } } else rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a call frame"); } } else { /* External function call, build the argument list. */ if (pFn->cArgs) { PVDSCRIPTARG paArgs = (PVDSCRIPTARG)RTMemAllocZ(pFn->cArgs * sizeof(VDSCRIPTARG)); if (paArgs) { for (unsigned i = 0; i < pFn->cArgs; i++) vdScriptInterpreterPopValue(pThis, &paArgs[i]); rc = pFn->Type.External.pfnCallback(paArgs, pFn->Type.External.pvUser); RTMemFree(paArgs); } else rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating argument array for external function call"); } else rc = pFn->Type.External.pfnCallback(NULL, pFn->Type.External.pvUser); } return rc; }
/** * Evaluate an expression. * * @returns VBox status code. * @param pThis The interpreter context. * @param pExpr The expression to evaluate. */ static int vdScriptInterpreterEvaluateExpression(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTEXPR pExpr) { int rc = VINF_SUCCESS; switch (pExpr->enmType) { case VDSCRIPTEXPRTYPE_PRIMARY_NUMCONST: { /* Push the numerical constant on the value stack. */ VDSCRIPTARG NumConst; NumConst.enmType = VDSCRIPTTYPE_UINT64; NumConst.u64 = pExpr->u64; rc = vdScriptInterpreterPushValue(pThis, &NumConst); break; } case VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST: { /* Push the string literal on the value stack. */ VDSCRIPTARG StringConst; StringConst.enmType = VDSCRIPTTYPE_STRING; StringConst.psz = pExpr->pszStr; rc = vdScriptInterpreterPushValue(pThis, &StringConst); break; } case VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN: { VDSCRIPTARG BoolConst; BoolConst.enmType = VDSCRIPTTYPE_BOOL; BoolConst.f = pExpr->f; rc = vdScriptInterpreterPushValue(pThis, &BoolConst); break; } case VDSCRIPTEXPRTYPE_PRIMARY_IDENTIFIER: { /* Look it up and push the value onto the value stack. */ PVDSCRIPTINTERPVAR pVar = vdScriptInterpreterGetVar(pThis, pExpr->pIde->aszIde); AssertPtrReturn(pVar, VERR_IPE_UNINITIALIZED_STATUS); rc = vdScriptInterpreterPushValue(pThis, &pVar->Value); break; } case VDSCRIPTEXPRTYPE_POSTFIX_INCREMENT: case VDSCRIPTEXPRTYPE_POSTFIX_DECREMENT: AssertMsgFailed(("TODO\n")); case VDSCRIPTEXPRTYPE_POSTFIX_FNCALL: { PVDSCRIPTFN pFn = (PVDSCRIPTFN)RTStrSpaceGet(&pThis->pScriptCtx->hStrSpaceFn, pExpr->FnCall.pFnIde->pIde->aszIde); if (pFn) { /* Push a function call control entry on the stack. */ PVDSCRIPTINTERPCTRL pCtrlFn = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl); if (pCtrlFn) { pCtrlFn->fEvalAst = false; pCtrlFn->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_FN_CALL; pCtrlFn->Ctrl.FnCall.pFn = pFn; vdScriptStackPush(&pThis->StackCtrl); /* Push parameter expressions on the stack. */ PVDSCRIPTASTEXPR pArg = RTListGetFirst(&pExpr->FnCall.ListArgs, VDSCRIPTASTEXPR, Core.ListNode); while (pArg) { rc = vdScriptInterpreterPushAstEntry(pThis, &pArg->Core); if (RT_FAILURE(rc)) break; pArg = RTListGetNext(&pExpr->FnCall.ListArgs, pArg, VDSCRIPTASTEXPR, Core.ListNode); } } } else AssertMsgFailed(("Invalid program given, unknown function: %s\n", pExpr->FnCall.pFnIde->pIde->aszIde)); break; } case VDSCRIPTEXPRTYPE_UNARY_INCREMENT: case VDSCRIPTEXPRTYPE_UNARY_DECREMENT: case VDSCRIPTEXPRTYPE_UNARY_POSSIGN: case VDSCRIPTEXPRTYPE_UNARY_NEGSIGN: case VDSCRIPTEXPRTYPE_UNARY_INVERT: case VDSCRIPTEXPRTYPE_UNARY_NEGATE: case VDSCRIPTEXPRTYPE_MULTIPLICATION: case VDSCRIPTEXPRTYPE_DIVISION: case VDSCRIPTEXPRTYPE_MODULUS: case VDSCRIPTEXPRTYPE_ADDITION: case VDSCRIPTEXPRTYPE_SUBTRACTION: case VDSCRIPTEXPRTYPE_LSR: case VDSCRIPTEXPRTYPE_LSL: case VDSCRIPTEXPRTYPE_LOWER: case VDSCRIPTEXPRTYPE_HIGHER: case VDSCRIPTEXPRTYPE_LOWEREQUAL: case VDSCRIPTEXPRTYPE_HIGHEREQUAL: case VDSCRIPTEXPRTYPE_EQUAL: case VDSCRIPTEXPRTYPE_NOTEQUAL: case VDSCRIPTEXPRTYPE_BITWISE_AND: case VDSCRIPTEXPRTYPE_BITWISE_XOR: case VDSCRIPTEXPRTYPE_BITWISE_OR: case VDSCRIPTEXPRTYPE_LOGICAL_AND: case VDSCRIPTEXPRTYPE_LOGICAL_OR: case VDSCRIPTEXPRTYPE_ASSIGN: case VDSCRIPTEXPRTYPE_ASSIGN_MULT: case VDSCRIPTEXPRTYPE_ASSIGN_DIV: case VDSCRIPTEXPRTYPE_ASSIGN_MOD: case VDSCRIPTEXPRTYPE_ASSIGN_ADD: case VDSCRIPTEXPRTYPE_ASSIGN_SUB: case VDSCRIPTEXPRTYPE_ASSIGN_LSL: case VDSCRIPTEXPRTYPE_ASSIGN_LSR: case VDSCRIPTEXPRTYPE_ASSIGN_AND: case VDSCRIPTEXPRTYPE_ASSIGN_XOR: case VDSCRIPTEXPRTYPE_ASSIGN_OR: case VDSCRIPTEXPRTYPE_ASSIGNMENT_LIST: AssertMsgFailed(("TODO\n")); default: AssertMsgFailed(("Invalid expression type: %d\n", pExpr->enmType)); } return rc; }