[PATCH 0/1] MR10536: vbscript: Fast-path stack_pop_bool for VT_BOOL.
Skip the expensive VariantChangeType call in stack_pop_bool when the variant is already VT_BOOL, which is the common case after comparison operators (OP_gt, OP_lt, OP_equal, etc.). Every If, ElseIf, While, and Do-While condition goes through jmp_false/jmp_true which calls stack_pop_bool, so this eliminates a redundant VT_BOOL-to-VT_BOOL conversion on every branch. This closed the If-condition gap from 1.5–2.1× slower than Windows down to 1.0–1.7× slower, with pure boolean tests reaching parity. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10536
From: Francis De Brabandere <francisdb@gmail.com> Skip the expensive VariantChangeType call in stack_pop_bool when the variant is already VT_BOOL, which is the common case after comparison operators (OP_gt, OP_lt, OP_equal, etc.). Every If, ElseIf, While, and Do-While condition goes through jmp_false/jmp_true which calls stack_pop_bool, so this eliminates a redundant VT_BOOL-to-VT_BOOL conversion on every branch. --- dlls/vbscript/interp.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index ad8ece8605d..07e2a2bd602 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -442,21 +442,26 @@ static HRESULT stack_pop_bool(exec_ctx_t *ctx, BOOL *b) { variant_val_t val; HRESULT hres; - VARIANT v; hres = stack_pop_val(ctx, &val); if(FAILED(hres)) return hres; - if (V_VT(val.v) == VT_NULL) - { + switch(V_VT(val.v)) { + case VT_BOOL: + *b = !!V_BOOL(val.v); + break; + case VT_NULL: *b = FALSE; - } - else - { + break; + default: { + VARIANT v; V_VT(&v) = VT_EMPTY; - if (SUCCEEDED(hres = VariantChangeType(&v, val.v, VARIANT_LOCALBOOL, VT_BOOL))) + hres = VariantChangeType(&v, val.v, VARIANT_LOCALBOOL, VT_BOOL); + if(SUCCEEDED(hres)) *b = !!V_BOOL(&v); + break; + } } release_val(&val); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10536
Jacek Caban (@jacek) commented about dlls/vbscript/interp.c:
- } - else - { + break; + default: { + VARIANT v; V_VT(&v) = VT_EMPTY; - if (SUCCEEDED(hres = VariantChangeType(&v, val.v, VARIANT_LOCALBOOL, VT_BOOL))) + hres = VariantChangeType(&v, val.v, VARIANT_LOCALBOOL, VT_BOOL); + if(SUCCEEDED(hres)) *b = !!V_BOOL(&v); + break; + } }
release_val(&val); It is not a big deal, but since this is all about performance, you could move `release_val` to the default case to skip it for fast paths that do not need it.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10536#note_134973
On Sat Apr 4 18:19:00 2026 +0000, Jacek Caban wrote:
It is not a big deal, but since this is all about performance, you could move `release_val` to the default case to skip it for fast paths that do not need it. done
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10536#note_135046
participants (3)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb) -
Jacek Caban (@jacek)