Changeset 44941 in vbox
- Timestamp:
- Mar 6, 2013 10:13:17 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 84147
- Location:
- trunk/src/VBox/Storage/testcase
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/testcase/VDScript.cpp
r44901 r44941 1 /** $Id$ */ 1 2 /** @file 2 3 * … … 370 371 bool fNewline = true; 371 372 372 if ( *pTokenizer->pszInput== '\r'373 if ( vdScriptTokenizerGetCh(pTokenizer) == '\r' 373 374 && vdScriptTokenizerPeekCh(pTokenizer) == '\n') 374 375 vdScriptTokenizerNewLine(pTokenizer, 2); 375 else if ( *pTokenizer->pszInput== '\n')376 else if (vdScriptTokenizerGetCh(pTokenizer) == '\n') 376 377 vdScriptTokenizerNewLine(pTokenizer, 1); 377 378 else … … 390 391 { 391 392 while ( !vdScriptTokenizerIsEos(pTokenizer) 392 && *pTokenizer->pszInput!= '*'393 && vdScriptTokenizerPeekCh(pTokenizer) != '/')393 && ( vdScriptTokenizerGetCh(pTokenizer) != '*' 394 || vdScriptTokenizerPeekCh(pTokenizer) != '/')) 394 395 { 395 396 if (!vdScriptTokenizerIsSkipNewLine(pTokenizer)) … … 504 505 for (unsigned i = 0; i < cchNumber; i++) 505 506 vdScriptTokenizerSkipCh(pTokenizer); 507 508 /* Check for a supported suffix, supported are K|M|G. */ 509 if (vdScriptTokenizerGetCh(pTokenizer) == 'K') 510 { 511 pToken->Class.NumConst.u64 *= _1K; 512 vdScriptTokenizerSkipCh(pTokenizer); 513 } 514 else if (vdScriptTokenizerGetCh(pTokenizer) == 'M') 515 { 516 pToken->Class.NumConst.u64 *= _1M; 517 vdScriptTokenizerSkipCh(pTokenizer); 518 } 519 else if (vdScriptTokenizerGetCh(pTokenizer) == 'G') 520 { 521 pToken->Class.NumConst.u64 *= _1G; 522 vdScriptTokenizerSkipCh(pTokenizer); 523 } 506 524 } 507 525 … … 931 949 PCVDSCRIPTTOKEN pToken = vdScriptTokenizerGetToken(pThis->pTokenizer); 932 950 pExpr->enmType = VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST; 933 pExpr->pszStr = RTStrDup (pToken->Class.StringConst.pszString);951 pExpr->pszStr = RTStrDupN(pToken->Class.StringConst.pszString, pToken->Class.StringConst.cchString); 934 952 vdScriptTokenizerConsume(pThis->pTokenizer); 935 953 936 954 if (!pExpr->pszStr) 937 955 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating string\n"); 956 } 957 else if (vdScriptTokenizerGetTokenClass(pThis->pTokenizer) == VDTOKENCLASS_KEYWORD) 958 { 959 PCVDSCRIPTTOKEN pToken = vdScriptTokenizerGetToken(pThis->pTokenizer); 960 pExpr->enmType = VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN; 961 962 if (pToken->Class.Keyword.enmKeyword == VDSCRIPTTOKENKEYWORD_TRUE) 963 pExpr->f = true; 964 else if (pToken->Class.Keyword.enmKeyword == VDSCRIPTTOKENKEYWORD_FALSE) 965 pExpr->f = false; 966 else 967 rc = vdScriptParserError(pThis, VERR_INVALID_PARAMETER, RT_SRC_POS, "Parser: Unexpected keyword, expected true or false\n"); 968 vdScriptTokenizerConsume(pThis->pTokenizer); 938 969 } 939 970 else … … 2505 2536 pAstNodeFn->pCompoundStmts = pAstCompound; 2506 2537 RTListAppend(&pThis->ListAst, &pAstNodeFn->Core.ListNode); 2538 2539 PVDSCRIPTFN pFn = (PVDSCRIPTFN)RTMemAllocZ(sizeof(VDSCRIPTFN)); 2540 if (pFn) 2541 { 2542 pFn->Core.pszString = pAstNodeFn->pFnIde->aszIde; 2543 pFn->Core.cchString = strlen(pFn->Core.pszString); 2544 pFn->fExternal = false; 2545 pFn->Type.Internal.pAstFn = pAstNodeFn; 2546 /** @todo: Parameters. */ 2547 RTStrSpaceInsert(&pThis->hStrSpaceFn, &pFn->Core); 2548 } 2549 else 2550 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory allocating memory for function\n"); 2507 2551 } 2508 2552 } … … 2600 2644 } 2601 2645 2602 DECLHIDDEN(int) VDScriptCtxCallbacksRegister(VDSCRIPTCTX hScriptCtx, P VDSCRIPTCALLBACK paCallbacks,2646 DECLHIDDEN(int) VDScriptCtxCallbacksRegister(VDSCRIPTCTX hScriptCtx, PCVDSCRIPTCALLBACK paCallbacks, 2603 2647 unsigned cCallbacks, void *pvUser) 2604 2648 { … … 2679 2723 PVDSCRIPTARG paArgs, unsigned cArgs) 2680 2724 { 2681 return VERR_NOT_IMPLEMENTED; 2682 } 2725 PVDSCRIPTCTXINT pThis = hScriptCtx; 2726 VDSCRIPTARG Ret; 2727 return vdScriptCtxInterprete(pThis, pszFnCall, paArgs, cArgs, &Ret); 2728 } -
trunk/src/VBox/Storage/testcase/VDScript.h
r44891 r44941 48 48 /** Pointer to a type. */ 49 49 typedef VDSCRIPTTYPE *PVDSCRIPTTYPE; 50 /** Pointer to a const type. */ 51 typedef const VDSCRIPTTYPE *PCVDSCRIPTTYPE; 50 52 51 53 /** … … 88 90 /** The return type of the function. */ 89 91 VDSCRIPTTYPE enmTypeReturn; 92 /** Pointer to the array of argument types. */ 93 PCVDSCRIPTTYPE paArgs; 90 94 /** Number of arguments this method takes. */ 91 95 unsigned cArgs; 92 /** Pointer to the array of argument types. */93 PVDSCRIPTTYPE paArgs;94 96 /** The callback handler. */ 95 97 PFNVDSCRIPTCALLBACK pfnCallback; … … 97 99 /** Pointer to a callback register entry. */ 98 100 typedef VDSCRIPTCALLBACK *PVDSCRIPTCALLBACK; 101 /** Pointer to a const callback register entry. */ 102 typedef const VDSCRIPTCALLBACK *PCVDSCRIPTCALLBACK; 99 103 100 104 /** … … 123 127 * @param pvUser Opaque user data to pass on the callback invocation. 124 128 */ 125 DECLHIDDEN(int) VDScriptCtxCallbacksRegister(VDSCRIPTCTX hScriptCtx, P VDSCRIPTCALLBACK paCallbacks,129 DECLHIDDEN(int) VDScriptCtxCallbacksRegister(VDSCRIPTCTX hScriptCtx, PCVDSCRIPTCALLBACK paCallbacks, 126 130 unsigned cCallbacks, void *pvUser); 127 131 -
trunk/src/VBox/Storage/testcase/VDScriptAst.cpp
r44891 r44941 1 /** $Id$ */ 1 2 /** @file 2 3 * … … 41 42 { 42 43 case VDSCRIPTEXPRTYPE_PRIMARY_NUMCONST: 44 case VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN: 43 45 break; 44 46 case VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST: … … 160 162 case VDSCRIPTSTMTTYPE_EXPRESSION: 161 163 { 162 RTListAppend(pList, &pStmt->pExpr->Core.ListNode); 164 if (pStmt->pExpr) 165 RTListAppend(pList, &pStmt->pExpr->Core.ListNode); 163 166 break; 164 167 } … … 215 218 AssertMsgFailedReturnVoid(("Invalid AST node statement type %d\n", 216 219 pStmt->enmStmtType)); 217 } 220 } 218 221 } 219 222 -
trunk/src/VBox/Storage/testcase/VDScriptAst.h
r44901 r44941 118 118 /** String constant. */ 119 119 VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST, 120 /** Boolean constant. */ 121 VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN, 120 122 /** Identifier. */ 121 123 VDSCRIPTEXPRTYPE_PRIMARY_IDENTIFIER, … … 222 224 /** String literal */ 223 225 const char *pszStr; 226 /** Boolean constant. */ 227 bool f; 224 228 /** List of expressions - VDSCRIPTASTEXPR. */ 225 229 RTLISTANCHOR ListExpr; -
trunk/src/VBox/Storage/testcase/VDScriptChecker.cpp
r44842 r44941 1 /** $Id$ */ 1 2 /** @file 2 3 * -
trunk/src/VBox/Storage/testcase/VDScriptInterp.cpp
r44901 r44941 1 /** $Id$ */ 1 2 /** @file 2 3 * … … 20 21 #include <iprt/assert.h> 21 22 #include <iprt/string.h> 23 #include <iprt/stream.h> 22 24 23 25 #include <VBox/log.h> … … 99 101 /** If statement to evaluate now, the guard is on the stack. */ 100 102 VDSCRIPTINTERPCTRLTYPE_IF, 103 /** While statement. */ 104 VDSCRIPTINTERPCTRLTYPE_WHILE, 105 /** for statement. */ 106 VDSCRIPTINTERPCTRLTYPE_FOR, 107 /** switch statement. */ 108 VDSCRIPTINTERPCTRLTYPE_SWITCH, 109 /** Compound statement. */ 110 VDSCRIPTINTERPCTRLTYPE_COMPOUND, 111 /** 32bit blowup. */ 101 112 VDSCRIPTINTERPCTRLTYPE_32BIT_HACK = 0x7fffffff 102 113 } VDSCRIPTINTERPCTRLTYPE; … … 125 136 { 126 137 /** Function to call. */ 127 PVDSCRIPT ASTFN pAstFn;138 PVDSCRIPTFN pFn; 128 139 } FnCall; 140 /** Compound statement. */ 141 struct 142 { 143 /** The compound statement node. */ 144 PVDSCRIPTASTSTMT pStmtCompound; 145 /** Current statement evaluated. */ 146 PVDSCRIPTASTSTMT pStmtCurr; 147 } Compound; 129 148 } Ctrl; 130 149 }; … … 144 163 static int vdScriptInterpreterError(PVDSCRIPTINTERPCTX pThis, int rc, RT_SRC_POS_DECL, const char *pszFmt, ...) 145 164 { 165 RTPrintf(pszFmt); 146 166 return rc; 147 167 } … … 168 188 DECLINLINE(int) vdScriptInterpreterPushValue(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTARG pVal) 169 189 { 170 PVDSCRIPTARG pValStack = (PVDSCRIPTARG)vdScriptStackGetU sed(&pThis->StackValues);190 PVDSCRIPTARG pValStack = (PVDSCRIPTARG)vdScriptStackGetUnused(&pThis->StackValues); 171 191 if (!pValStack) 172 192 return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory pushing a value on the value stack"); … … 202 222 203 223 /** 224 * Pushes a compound statement control entry onto the stack. 225 * 226 * @returns VBox status code. 227 * @param pThis The interpreter context. 228 * @param pStmtFirst The first statement of the compound statement 229 */ 230 DECLINLINE(int) vdScriptInterpreterPushCompoundCtrlEntry(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt) 231 { 232 PVDSCRIPTINTERPCTRL pCtrl = NULL; 233 234 pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl); 235 if (pCtrl) 236 { 237 pCtrl->fEvalAst = false; 238 pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_COMPOUND; 239 pCtrl->Ctrl.Compound.pStmtCompound = pStmt; 240 pCtrl->Ctrl.Compound.pStmtCurr = RTListGetFirst(&pStmt->Compound.ListStmts, VDSCRIPTASTSTMT, Core.ListNode); 241 vdScriptStackPush(&pThis->StackCtrl); 242 return VINF_SUCCESS; 243 } 244 245 return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack"); 246 } 247 248 /** 204 249 * Pushes an AST node onto the control stack. 205 250 * … … 227 272 228 273 /** 274 * Destroy variable string space callback. 275 */ 276 static DECLCALLBACK(int) vdScriptInterpreterVarSpaceDestroy(PRTSTRSPACECORE pStr, void *pvUser) 277 { 278 RTMemFree(pStr); 279 return VINF_SUCCESS; 280 } 281 282 /** 283 * Setsup a new scope in the current function call. 284 * 285 * @returns VBox status code. 286 * @param pThis The interpreter context. 287 */ 288 static int vdScriptInterpreterScopeCreate(PVDSCRIPTINTERPCTX pThis) 289 { 290 int rc = VINF_SUCCESS; 291 PVDSCRIPTINTERPSCOPE pScope = (PVDSCRIPTINTERPSCOPE)RTMemAllocZ(sizeof(VDSCRIPTINTERPSCOPE)); 292 if (pScope) 293 { 294 pScope->pParent = pThis->pFnCallCurr->pScopeCurr; 295 pScope->hStrSpaceVar = NULL; 296 pThis->pFnCallCurr->pScopeCurr = pScope; 297 } 298 else 299 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory allocating new scope"); 300 301 return rc; 302 } 303 304 /** 305 * Destroys the current scope. 306 * 307 * @returns nothing. 308 * @param pThis The interpreter context. 309 */ 310 static void vdScriptInterpreterScopeDestroyCurr(PVDSCRIPTINTERPCTX pThis) 311 { 312 AssertMsgReturnVoid(pThis->pFnCallCurr->pScopeCurr != &pThis->pFnCallCurr->ScopeRoot, 313 ("Current scope is root scope of function call\n")); 314 315 PVDSCRIPTINTERPSCOPE pScope = pThis->pFnCallCurr->pScopeCurr; 316 pThis->pFnCallCurr->pScopeCurr = pScope->pParent; 317 RTStrSpaceDestroy(&pScope->hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL); 318 RTMemFree(pScope); 319 } 320 321 /** 322 * Get the content of the given variable identifier from the current or parent scope. 323 */ 324 static PVDSCRIPTINTERPVAR vdScriptInterpreterGetVar(PVDSCRIPTINTERPCTX pThis, const char *pszVar) 325 { 326 PVDSCRIPTINTERPSCOPE pScopeCurr = pThis->pFnCallCurr->pScopeCurr; 327 PVDSCRIPTINTERPVAR pVar = NULL; 328 329 while ( !pVar 330 && pScopeCurr) 331 { 332 pVar = (PVDSCRIPTINTERPVAR)RTStrSpaceGet(&pScopeCurr->hStrSpaceVar, pszVar); 333 if (pVar) 334 break; 335 pScopeCurr = pScopeCurr->pParent; 336 } 337 338 339 return pVar; 340 } 341 342 /** 343 * Evaluate an expression. 344 * 345 * @returns VBox status code. 346 * @param pThis The interpreter context. 347 * @param pExpr The expression to evaluate. 348 */ 349 static int vdScriptInterpreterEvaluateExpression(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTEXPR pExpr) 350 { 351 int rc = VINF_SUCCESS; 352 353 switch (pExpr->enmType) 354 { 355 case VDSCRIPTEXPRTYPE_PRIMARY_NUMCONST: 356 { 357 /* Push the numerical constant on the value stack. */ 358 VDSCRIPTARG NumConst; 359 NumConst.enmType = VDSCRIPTTYPE_UINT64; 360 NumConst.u64 = pExpr->u64; 361 rc = vdScriptInterpreterPushValue(pThis, &NumConst); 362 break; 363 } 364 case VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST: 365 { 366 /* Push the string literal on the value stack. */ 367 VDSCRIPTARG StringConst; 368 StringConst.enmType = VDSCRIPTTYPE_STRING; 369 StringConst.psz = pExpr->pszStr; 370 rc = vdScriptInterpreterPushValue(pThis, &StringConst); 371 break; 372 } 373 case VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN: 374 { 375 VDSCRIPTARG BoolConst; 376 BoolConst.enmType = VDSCRIPTTYPE_BOOL; 377 BoolConst.f = pExpr->f; 378 rc = vdScriptInterpreterPushValue(pThis, &BoolConst); 379 break; 380 } 381 case VDSCRIPTEXPRTYPE_PRIMARY_IDENTIFIER: 382 { 383 /* Look it up and push the value onto the value stack. */ 384 PVDSCRIPTINTERPVAR pVar = vdScriptInterpreterGetVar(pThis, pExpr->pIde->aszIde); 385 386 AssertPtrReturn(pVar, VERR_IPE_UNINITIALIZED_STATUS); 387 rc = vdScriptInterpreterPushValue(pThis, &pVar->Value); 388 break; 389 } 390 case VDSCRIPTEXPRTYPE_POSTFIX_INCREMENT: 391 case VDSCRIPTEXPRTYPE_POSTFIX_DECREMENT: 392 AssertMsgFailed(("TODO\n")); 393 case VDSCRIPTEXPRTYPE_POSTFIX_FNCALL: 394 { 395 PVDSCRIPTFN pFn = (PVDSCRIPTFN)RTStrSpaceGet(&pThis->pScriptCtx->hStrSpaceFn, pExpr->FnCall.pFnIde->pIde->aszIde); 396 if (pFn) 397 { 398 /* Push a function call control entry on the stack. */ 399 PVDSCRIPTINTERPCTRL pCtrlFn = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl); 400 if (pCtrlFn) 401 { 402 pCtrlFn->fEvalAst = false; 403 pCtrlFn->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_FN_CALL; 404 pCtrlFn->Ctrl.FnCall.pFn = pFn; 405 vdScriptStackPush(&pThis->StackCtrl); 406 407 /* Push parameter expressions on the stack. */ 408 PVDSCRIPTASTEXPR pArg = RTListGetFirst(&pExpr->FnCall.ListArgs, VDSCRIPTASTEXPR, Core.ListNode); 409 while (pArg) 410 { 411 rc = vdScriptInterpreterPushAstEntry(pThis, &pArg->Core); 412 if (RT_FAILURE(rc)) 413 break; 414 pArg = RTListGetNext(&pExpr->FnCall.ListArgs, pArg, VDSCRIPTASTEXPR, Core.ListNode); 415 } 416 } 417 } 418 else 419 AssertMsgFailed(("Invalid program given, unknown function: %s\n", pExpr->FnCall.pFnIde->pIde->aszIde)); 420 break; 421 } 422 case VDSCRIPTEXPRTYPE_UNARY_INCREMENT: 423 case VDSCRIPTEXPRTYPE_UNARY_DECREMENT: 424 case VDSCRIPTEXPRTYPE_UNARY_POSSIGN: 425 case VDSCRIPTEXPRTYPE_UNARY_NEGSIGN: 426 case VDSCRIPTEXPRTYPE_UNARY_INVERT: 427 case VDSCRIPTEXPRTYPE_UNARY_NEGATE: 428 case VDSCRIPTEXPRTYPE_MULTIPLICATION: 429 case VDSCRIPTEXPRTYPE_DIVISION: 430 case VDSCRIPTEXPRTYPE_MODULUS: 431 case VDSCRIPTEXPRTYPE_ADDITION: 432 case VDSCRIPTEXPRTYPE_SUBTRACTION: 433 case VDSCRIPTEXPRTYPE_LSR: 434 case VDSCRIPTEXPRTYPE_LSL: 435 case VDSCRIPTEXPRTYPE_LOWER: 436 case VDSCRIPTEXPRTYPE_HIGHER: 437 case VDSCRIPTEXPRTYPE_LOWEREQUAL: 438 case VDSCRIPTEXPRTYPE_HIGHEREQUAL: 439 case VDSCRIPTEXPRTYPE_EQUAL: 440 case VDSCRIPTEXPRTYPE_NOTEQUAL: 441 case VDSCRIPTEXPRTYPE_BITWISE_AND: 442 case VDSCRIPTEXPRTYPE_BITWISE_XOR: 443 case VDSCRIPTEXPRTYPE_BITWISE_OR: 444 case VDSCRIPTEXPRTYPE_LOGICAL_AND: 445 case VDSCRIPTEXPRTYPE_LOGICAL_OR: 446 case VDSCRIPTEXPRTYPE_ASSIGN: 447 case VDSCRIPTEXPRTYPE_ASSIGN_MULT: 448 case VDSCRIPTEXPRTYPE_ASSIGN_DIV: 449 case VDSCRIPTEXPRTYPE_ASSIGN_MOD: 450 case VDSCRIPTEXPRTYPE_ASSIGN_ADD: 451 case VDSCRIPTEXPRTYPE_ASSIGN_SUB: 452 case VDSCRIPTEXPRTYPE_ASSIGN_LSL: 453 case VDSCRIPTEXPRTYPE_ASSIGN_LSR: 454 case VDSCRIPTEXPRTYPE_ASSIGN_AND: 455 case VDSCRIPTEXPRTYPE_ASSIGN_XOR: 456 case VDSCRIPTEXPRTYPE_ASSIGN_OR: 457 case VDSCRIPTEXPRTYPE_ASSIGNMENT_LIST: 458 AssertMsgFailed(("TODO\n")); 459 default: 460 AssertMsgFailed(("Invalid expression type: %d\n", pExpr->enmType)); 461 } 462 return rc; 463 } 464 465 /** 229 466 * Evaluate a statement. 230 467 * … … 235 472 static int vdScriptInterpreterEvaluateStatement(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt) 236 473 { 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 */ 248 static int vdScriptInterpreterEvaluateExpression(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTEXPR pExpr) 249 { 250 int rc = VERR_NOT_IMPLEMENTED; 474 int rc = VINF_SUCCESS; 475 476 switch (pStmt->enmStmtType) 477 { 478 case VDSCRIPTSTMTTYPE_COMPOUND: 479 { 480 /* Setup new scope. */ 481 rc = vdScriptInterpreterScopeCreate(pThis); 482 if (RT_SUCCESS(rc)) 483 { 484 /** @todo: Declarations */ 485 rc = vdScriptInterpreterPushCompoundCtrlEntry(pThis, pStmt); 486 } 487 break; 488 } 489 case VDSCRIPTSTMTTYPE_EXPRESSION: 490 { 491 rc = vdScriptInterpreterPushAstEntry(pThis, &pStmt->pExpr->Core); 492 break; 493 } 494 case VDSCRIPTSTMTTYPE_IF: 495 case VDSCRIPTSTMTTYPE_SWITCH: 496 case VDSCRIPTSTMTTYPE_WHILE: 497 case VDSCRIPTSTMTTYPE_FOR: 498 case VDSCRIPTSTMTTYPE_CONTINUE: 499 case VDSCRIPTSTMTTYPE_BREAK: 500 case VDSCRIPTSTMTTYPE_RETURN: 501 case VDSCRIPTSTMTTYPE_CASE: 502 case VDSCRIPTSTMTTYPE_DEFAULT: 503 default: 504 AssertMsgFailed(("Invalid statement type: %d\n", pStmt->enmStmtType)); 505 } 506 251 507 return rc; 252 508 } … … 267 523 case VDSCRIPTASTCLASS_DECLARATION: 268 524 { 269 break; 270 } 525 AssertMsgFailed(("TODO\n")); 526 break; 527 } 528 case VDSCRIPTASTCLASS_STATEMENT: 529 { 530 rc = vdScriptInterpreterEvaluateStatement(pThis, (PVDSCRIPTASTSTMT)pAstNode); 531 break; 532 } 533 case VDSCRIPTASTCLASS_EXPRESSION: 534 { 535 rc = vdScriptInterpreterEvaluateExpression(pThis, (PVDSCRIPTASTEXPR)pAstNode); 536 break; 537 } 538 /* These should never ever appear here. */ 271 539 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 540 case VDSCRIPTASTCLASS_FUNCTION: 296 541 case VDSCRIPTASTCLASS_FUNCTIONARG: … … 304 549 305 550 /** 306 * Destroy variable string space callback.307 */308 static DECLCALLBACK(int) vdScriptInterpreterVarSpaceDestroy(PRTSTRSPACECORE pStr, void *pvUser)309 {310 RTMemFree(pStr);311 return VINF_SUCCESS;312 }313 314 /**315 551 * Evaluate a function call. 316 552 * 317 553 * @returns VBox status code. 318 554 * @param pThis The interpreter context. 319 * @param 320 */ 321 static int vdScriptInterpreterFnCall(PVDSCRIPTINTERPCTX pThis, PVDSCRIPT ASTFN pAstFn)555 * @param pFn The function execute. 556 */ 557 static int vdScriptInterpreterFnCall(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTFN pFn) 322 558 { 323 559 int rc = VINF_SUCCESS; 324 560 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) 561 if (!pFn->fExternal) 562 { 563 PVDSCRIPTASTFN pAstFn = pFn->Type.Internal.pAstFn; 564 565 /* Add function call cleanup marker on the stack first. */ 566 rc = vdScriptInterpreterPushNonDataCtrlEntry(pThis, VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP); 567 if (RT_SUCCESS(rc)) 568 { 569 /* Create function call frame and set it up. */ 570 PVDSCRIPTINTERPFNCALL pFnCall = (PVDSCRIPTINTERPFNCALL)RTMemAllocZ(sizeof(VDSCRIPTINTERPFNCALL)); 571 if (pFnCall) 572 { 573 pFnCall->pCaller = pThis->pFnCallCurr; 574 pFnCall->ScopeRoot.pParent = NULL; 575 pFnCall->ScopeRoot.hStrSpaceVar = NULL; 576 pFnCall->pScopeCurr = &pFnCall->ScopeRoot; 577 578 /* Add the variables, remember order. The first variable in the argument has the value at the top of the value stack. */ 579 PVDSCRIPTASTFNARG pArg = RTListGetFirst(&pAstFn->ListArgs, VDSCRIPTASTFNARG, Core.ListNode); 580 for (unsigned i = 0; i < pAstFn->cArgs; i++) 343 581 { 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); 582 PVDSCRIPTINTERPVAR pVar = (PVDSCRIPTINTERPVAR)RTMemAllocZ(sizeof(VDSCRIPTINTERPVAR)); 583 if (pVar) 584 { 585 pVar->Core.pszString = pArg->pArgIde->aszIde; 586 pVar->Core.cchString = pArg->pArgIde->cchIde; 587 vdScriptInterpreterPopValue(pThis, &pVar->Value); 588 bool fInserted = RTStrSpaceInsert(&pFnCall->ScopeRoot.hStrSpaceVar, &pVar->Core); 589 Assert(fInserted); 590 } 591 else 592 { 593 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a variable"); 594 break; 595 } 596 pArg = RTListGetNext(&pAstFn->ListArgs, pArg, VDSCRIPTASTFNARG, Core.ListNode); 349 597 } 350 else 598 599 if (RT_SUCCESS(rc)) 351 600 { 352 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a variable"); 353 break; 601 /* 602 * Push compount statement on the control stack and make the newly created 603 * call frame the current one. 604 */ 605 rc = vdScriptInterpreterPushAstEntry(pThis, &pAstFn->pCompoundStmts->Core); 606 if (RT_SUCCESS(rc)) 607 pThis->pFnCallCurr = pFnCall; 354 608 } 355 pArg = RTListGetNext(&pAstFn->ListArgs, pArg, VDSCRIPTASTFNARG, Core.ListNode); 609 610 if (RT_FAILURE(rc)) 611 { 612 RTStrSpaceDestroy(&pFnCall->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL); 613 RTMemFree(pFnCall); 614 } 356 615 } 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); 616 else 617 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a call frame"); 618 } 619 } 620 else 621 { 622 /* External function call, build the argument list. */ 623 if (pFn->cArgs) 624 { 625 PVDSCRIPTARG paArgs = (PVDSCRIPTARG)RTMemAllocZ(pFn->cArgs * sizeof(VDSCRIPTARG)); 626 if (paArgs) 627 { 628 for (unsigned i = 0; i < pFn->cArgs; i++) 629 vdScriptInterpreterPopValue(pThis, &paArgs[i]); 630 631 rc = pFn->Type.External.pfnCallback(paArgs, pFn->Type.External.pvUser); 632 RTMemFree(paArgs); 633 } 634 else 635 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, 636 "Out of memory creating argument array for external function call"); 637 } 638 else 639 rc = pFn->Type.External.pfnCallback(NULL, pFn->Type.External.pvUser); 640 } 641 642 return rc; 643 } 644 645 /** 646 * Evaluate interpreter control statement. 647 * 648 * @returns VBox status code. 649 * @param pThis The interpreter context. 650 * @param pCtrl The control entry to evaluate. 651 */ 652 static int vdScriptInterpreterEvaluateCtrlEntry(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTINTERPCTRL pCtrl) 653 { 654 int rc = VINF_SUCCESS; 655 656 Assert(!pCtrl->fEvalAst); 657 switch (pCtrl->Ctrl.enmCtrlType) 658 { 659 case VDSCRIPTINTERPCTRLTYPE_FN_CALL: 660 { 661 PVDSCRIPTFN pFn = pCtrl->Ctrl.FnCall.pFn; 662 663 vdScriptStackPop(&pThis->StackCtrl); 664 rc = vdScriptInterpreterFnCall(pThis, pFn); 665 break; 666 } 667 case VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP: 668 { 669 vdScriptStackPop(&pThis->StackCtrl); 670 671 /* Delete function call entry. */ 672 AssertPtr(pThis->pFnCallCurr); 673 PVDSCRIPTINTERPFNCALL pFnCallFree = pThis->pFnCallCurr; 674 675 pThis->pFnCallCurr = pFnCallFree->pCaller; 676 Assert(pFnCallFree->pScopeCurr == &pFnCallFree->ScopeRoot); 677 RTStrSpaceDestroy(&pFnCallFree->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL); 678 RTMemFree(pFnCallFree); 679 break; 680 } 681 case VDSCRIPTINTERPCTRLTYPE_COMPOUND: 682 { 683 if (!pCtrl->Ctrl.Compound.pStmtCurr) 684 { 685 /* Evaluated last statement, cleanup and remove the control statement from the stack. */ 686 vdScriptInterpreterScopeDestroyCurr(pThis); 687 vdScriptStackPop(&pThis->StackCtrl); 688 } 689 else 690 { 691 /* Push the current statement onto the control stack and move on. */ 692 rc = vdScriptInterpreterPushAstEntry(pThis, &pCtrl->Ctrl.Compound.pStmtCurr->Core); 365 693 if (RT_SUCCESS(rc)) 366 pThis->pFnCallCurr = pFnCall; 694 { 695 pCtrl->Ctrl.Compound.pStmtCurr = RTListGetNext(&pCtrl->Ctrl.Compound.pStmtCompound->Compound.ListStmts, 696 pCtrl->Ctrl.Compound.pStmtCurr, VDSCRIPTASTSTMT, Core.ListNode); 697 } 367 698 } 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"); 699 break; 700 } 701 default: 702 AssertMsgFailed(("Invalid evaluation control type on the stack: %d\n", 703 pCtrl->Ctrl.enmCtrlType)); 377 704 } 378 705 … … 402 729 } 403 730 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 } 731 rc = vdScriptInterpreterEvaluateCtrlEntry(pThis, pCtrl); 732 434 733 pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl); 435 734 } … … 472 771 if (RT_SUCCESS(rc)) 473 772 { 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);773 /* Setup function call frame and parameters. */ 774 rc = vdScriptInterpreterFnCall(&InterpCtx, pFn); 775 if (RT_SUCCESS(rc)) 776 { 777 /* Run the interpreter. */ 778 rc = vdScriptInterpreterEvaluate(&InterpCtx); 779 vdScriptStackDestroy(&InterpCtx.StackValues); 780 vdScriptStackDestroy(&InterpCtx.StackCtrl); 781 } 483 782 } 484 783 } -
trunk/src/VBox/Storage/testcase/VDScriptStack.h
r44901 r44941 56 56 57 57 /** 58 * Destroys the given stack freeing all memory. 59 * 60 * @returns nothing. 61 * @param pStack The stack to destroy. 62 */ 63 DECLINLINE(void) vdScriptStackDestroy(PVDSCRIPTSTACK pStack) 64 { 65 if (pStack->pvStack) 66 RTMemFree(pStack->pvStack); 67 pStack->cbStackEntry = 0; 68 pStack->pvStack = NULL; 69 pStack->cOnStack = 0; 70 pStack->cOnStackMax = 0; 71 } 72 73 /** 58 74 * Gets the topmost unused stack entry. 59 75 * … … 81 97 } 82 98 83 if (pStack->cOnStack >=pStack->cOnStackMax)99 if (pStack->cOnStack < pStack->cOnStackMax) 84 100 pvElem = (char *)pStack->pvStack + pStack->cOnStack * pStack->cbStackEntry; 85 101
Note:
See TracChangeset
for help on using the changeset viewer.