vbscript: Added support for script context in ParseScriptText.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2018-03-16 23:34:52 +01:00 committed by Alexandre Julliard
parent aa5b68ac40
commit 7e10941083
5 changed files with 80 additions and 12 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -342,6 +342,7 @@ struct _vbscode_t {
BOOL pending_exec;
function_t main_code;
IDispatch *context;
BSTR *bstr_pool;
unsigned bstr_pool_size;