Module: wine Branch: master Commit: 7e109410836f18a67418209a4b73dcdb513532f8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=7e109410836f18a67418209a4...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Mar 16 23:34:52 2018 +0100
vbscript: Added support for script context in ParseScriptText.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/vbscript/compile.c | 15 +++---------- dlls/vbscript/interp.c | 10 +++++++++ dlls/vbscript/tests/run.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/vbscript/vbscript.c | 12 +++++++++++ dlls/vbscript/vbscript.h | 1 + 5 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index c8189d6..302804f 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1746,6 +1746,8 @@ void release_vbscode(vbscode_t *code) for(i=0; i < code->bstr_cnt; i++) SysFreeString(code->bstr_pool[i]);
+ if(code->context) + IDispatch_Release(code->context); heap_pool_free(&code->heap);
heap_free(code->bstr_pool); @@ -1758,7 +1760,7 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source) { vbscode_t *ret;
- ret = heap_alloc(sizeof(*ret)); + ret = heap_alloc_zero(sizeof(*ret)); if(!ret) return NULL;
@@ -1780,19 +1782,8 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
ret->option_explicit = ctx->parser.option_explicit;
- ret->bstr_pool = NULL; - ret->bstr_pool_size = 0; - ret->bstr_cnt = 0; - ret->pending_exec = FALSE; - ret->main_code.type = FUNC_GLOBAL; - ret->main_code.name = NULL; ret->main_code.code_ctx = ret; - ret->main_code.vars = NULL; - ret->main_code.var_cnt = 0; - ret->main_code.array_cnt = 0; - ret->main_code.arg_cnt = 0; - ret->main_code.args = NULL;
list_init(&ret->entry); return ret; diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 4f746c7..b46bd01 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -154,6 +154,16 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ } }
+ if(ctx->func->code_ctx->context) { + hres = disp_get_id(ctx->func->code_ctx->context, name, invoke_type, TRUE, &id); + if(SUCCEEDED(hres)) { + ref->type = REF_DISP; + ref->u.d.disp = ctx->func->code_ctx->context; + ref->u.d.id = id; + return S_OK; + } + } + if(ctx->func->type != FUNC_GLOBAL && lookup_dynamic_vars(ctx->script->global_vars, name, ref)) return S_OK;
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index ee811c6..9172add 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -1804,6 +1804,59 @@ static HRESULT parse_script_ar(const char *src) return hres; }
+static void test_parse_context(void) +{ + IActiveScriptParse *parser; + IActiveScript *engine; + BSTR str; + HRESULT hres; + + static const WCHAR xW[] = {'x',0}; + static const WCHAR yW[] = {'y',0}; + + engine = create_and_init_script(0); + if(!engine) + return; + + hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres); + + /* unknown identifier context is not a valid argument */ + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, yW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("class Cl\n" + " Public Sub ClMethod\n" + " Call reportSuccess()\n" + " End Sub\n" + "End Class\n" + "Dim x\n" + "set x = new Cl\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + /* known global variable is not a valid context */ + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, xW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + SET_EXPECT(global_success_d); + SET_EXPECT(global_success_i); + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, testW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + CHECK_CALLED(global_success_d); + CHECK_CALLED(global_success_i); + + IActiveScriptParse_Release(parser); + close_script(engine); +} + static void parse_script_a(const char *src) { parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src); @@ -2334,6 +2387,7 @@ static void run_tests(void) test_procedures(); test_gc(); test_msgbox(); + test_parse_context(); }
static BOOL check_vbscript(void) diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 054d53b..b97cf5a 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -636,6 +636,7 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { VBScript *This = impl_from_IActiveScriptParse(iface); + IDispatch *context = NULL; vbscode_t *code; HRESULT hres;
@@ -646,10 +647,21 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED;
+ if(pstrItemName) { + context = lookup_named_item(This->ctx, pstrItemName, 0); + if(!context) { + WARN("Inknown context %s\n", debugstr_w(pstrItemName)); + return E_INVALIDARG; + } + } + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code); if(FAILED(hres)) return hres;
+ if(context) + IDispatch_AddRef(code->context = context); + if(!is_started(This)) { code->pending_exec = TRUE; return S_OK; diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 42b3cd1..5877762 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -342,6 +342,7 @@ struct _vbscode_t {
BOOL pending_exec; function_t main_code; + IDispatch *context;
BSTR *bstr_pool; unsigned bstr_pool_size;