To simplify the amount of special cases both in ParseScriptText and ParseProcedureText, add a new pseudo statement and opcode to return the expression and value at the top of the stack, respectively. Script texts that have this flag will be parsed specially as a single expression with such a statement at the end.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/vbscript/compile.c | 22 ++++++++++++++++++++-- dlls/vbscript/interp.c | 26 ++++++++++++++++++++++++-- dlls/vbscript/lex.c | 6 ++++++ dlls/vbscript/parse.h | 10 ++++++++-- dlls/vbscript/parser.y | 31 ++++++++++++++++++++++++++++--- dlls/vbscript/vbscript.c | 14 +++++++------- dlls/vbscript/vbscript.h | 3 ++- 7 files changed, 95 insertions(+), 17 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 1f4a7d3..0527297 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1196,6 +1196,21 @@ static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t return push_instr_int(ctx, OP_errmode, stat->resume_next); }
+static HRESULT compile_retval_statement(compile_ctx_t *ctx, retval_statement_t *stat) +{ + HRESULT hres; + + hres = compile_expression(ctx, stat->expr); + if(FAILED(hres)) + return hres; + + hres = push_instr(ctx, OP_retval); + if(FAILED(hres)) + return hres; + + return S_OK; +} + static HRESULT compile_statement(compile_ctx_t *ctx, statement_ctx_t *stat_ctx, statement_t *stat) { HRESULT hres; @@ -1267,6 +1282,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_ctx_t *stat_ctx, case STAT_WHILELOOP: hres = compile_while_statement(ctx, (while_statement_t*)stat); break; + case STAT_RETVAL: + hres = compile_retval_statement(ctx, (retval_statement_t*)stat); + break; default: FIXME("Unimplemented statement type %d\n", stat->type); hres = E_NOTIMPL; @@ -1795,7 +1813,7 @@ static void release_compiler(compile_ctx_t *ctx) release_vbscode(ctx->code); }
-HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, vbscode_t **ret) +HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, vbscode_t **ret) { function_t *new_func; function_decl_t *func_decl; @@ -1804,7 +1822,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli vbscode_t *code; HRESULT hres;
- hres = parse_script(&ctx.parser, src, delimiter); + hres = parse_script(&ctx.parser, src, delimiter, flags); if(FAILED(hres)) return hres;
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 629e833..6b9fd60 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -1258,6 +1258,30 @@ static HRESULT interp_ret(exec_ctx_t *ctx) return S_OK; }
+static HRESULT interp_retval(exec_ctx_t *ctx) +{ + variant_val_t val; + HRESULT hres; + + TRACE("\n"); + + hres = stack_pop_val(ctx, &val); + if(FAILED(hres)) + return hres; + + if(val.owned) { + VariantClear(&ctx->ret_val); + ctx->ret_val = *val.v; + } + else { + hres = VariantCopy(&ctx->ret_val, val.v); + if(FAILED(hres)) + return hres; + } + + return S_OK; +} + static HRESULT interp_stop(exec_ctx_t *ctx) { WARN("\n"); @@ -2179,8 +2203,6 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, vbdisp_t *vbthis, DISPP }
assert(!exec.top); - if(func->type != FUNC_FUNCTION && func->type != FUNC_PROPGET && func->type != FUNC_DEFGET) - assert(V_VT(&exec.ret_val) == VT_EMPTY);
if(SUCCEEDED(hres) && res) { *res = exec.ret_val; diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index 4bcf810..510ac09 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -493,6 +493,12 @@ int parser_lex(void *lval, parser_ctx_t *ctx) { int ret;
+ if (ctx->last_token == tEXPRESSION) + { + ctx->last_token = tNL; + return tEXPRESSION; + } + while(1) { ret = parse_next_token(lval, ctx); if(ret == '_') { diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 867d45f..659fefa 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -118,7 +118,8 @@ typedef enum { STAT_STOP, STAT_UNTIL, STAT_WHILE, - STAT_WHILELOOP + STAT_WHILELOOP, + STAT_RETVAL } statement_type_t;
typedef struct _statement_t { @@ -248,6 +249,11 @@ typedef struct { case_clausule_t *case_clausules; } select_statement_t;
+typedef struct { + statement_t stat; + expression_t *expr; +} retval_statement_t; + typedef struct { const WCHAR *code; const WCHAR *ptr; @@ -268,7 +274,7 @@ typedef struct { heap_pool_t heap; } parser_ctx_t;
-HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; +HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN; void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN; int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN; void *parser_alloc(parser_ctx_t*,size_t) DECLSPEC_HIDDEN; diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index d4f5eb3..8ecdf47 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -28,6 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript); static int parser_error(parser_ctx_t *,const char*);
static void parse_complete(parser_ctx_t*,BOOL); +static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr);
static void source_add_statement(parser_ctx_t*,statement_t*); static void source_add_class(parser_ctx_t*,class_decl_t*); @@ -102,7 +103,7 @@ static statement_t *link_statements(statement_t*,statement_t*); double dbl; }
-%token tEOF tNL tEMPTYBRACKETS +%token tEXPRESSION tEOF tNL tEMPTYBRACKETS %token tLTEQ tGTEQ tNEQ %token tSTOP tME tREM %token <string> tTRUE tFALSE @@ -123,7 +124,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %token <dbl> tDouble
%type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt BodyStatements IfStatement Else_opt -%type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression +%type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression %type <expression> ConstExpression NumericLiteralExpression @@ -145,6 +146,7 @@ static statement_t *link_statements(statement_t*,statement_t*);
Program : OptionExplicit_opt SourceElements tEOF { parse_complete(ctx, $1); } + | tEXPRESSION ExpressionNl_opt tEOF { handle_isexpression_script(ctx, $2); }
OptionExplicit_opt : /* empty */ { $$ = FALSE; } @@ -155,6 +157,10 @@ SourceElements | SourceElements StatementNl { source_add_statement(ctx, $2); } | SourceElements ClassDeclaration { source_add_class(ctx, $2); }
+ExpressionNl_opt + : /* empty */ { $$ = NULL; } + | Expression tNL { $$ = $1; } + BodyStatements : /* empty */ { $$ = NULL; } | Statement { $$ = $1; } @@ -553,6 +559,22 @@ static void parse_complete(parser_ctx_t *ctx, BOOL option_explicit) ctx->option_explicit = option_explicit; }
+static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr) +{ + retval_statement_t *stat; + + ctx->parse_complete = TRUE; + if(!expr) + return; + + stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat)); + if(!stat) + return; + + stat->expr = expr; + ctx->stats = &stat->stat; +} + static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size) { expression_t *expr; @@ -1033,7 +1055,7 @@ void *parser_alloc(parser_ctx_t *ctx, size_t size) return ret; }
-HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter) +HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, DWORD flags) { static const WCHAR html_delimiterW[] = {'<','/','s','c','r','i','p','t','>',0};
@@ -1052,6 +1074,9 @@ HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite ctx->option_explicit = FALSE; ctx->is_html = delimiter && !wcsicmp(delimiter, html_delimiterW);
+ if(flags & SCRIPTTEXT_ISEXPRESSION) + ctx->last_token = tEXPRESSION; + parser_parse(ctx);
if(FAILED(ctx->hres)) diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index aa90b94..aa768a5 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -76,14 +76,14 @@ static inline BOOL is_started(VBScript *This) || This->state == SCRIPTSTATE_DISCONNECTED; }
-static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code) +static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res) { HRESULT hres;
code->pending_exec = FALSE;
IActiveScriptSite_OnEnterScript(ctx->site); - hres = exec_script(ctx, &code->main_code, NULL, NULL, NULL); + hres = exec_script(ctx, &code->main_code, NULL, NULL, res); IActiveScriptSite_OnLeaveScript(ctx->site);
return hres; @@ -95,7 +95,7 @@ static void exec_queued_code(script_ctx_t *ctx)
LIST_FOR_EACH_ENTRY(iter, &ctx->code_list, vbscode_t, entry) { if(iter->pending_exec) - exec_global_code(ctx, iter); + exec_global_code(ctx, iter, NULL); } }
@@ -719,19 +719,19 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, } }
- hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code); + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, dwFlags, &code); if(FAILED(hres)) return hres;
if(context) IDispatch_AddRef(code->context = context);
- if(!is_started(This)) { + if(!(dwFlags & SCRIPTTEXT_ISEXPRESSION) && !is_started(This)) { code->pending_exec = TRUE; return S_OK; }
- return exec_global_code(This->ctx, code); + return exec_global_code(This->ctx, code, pvarResult); }
static const IActiveScriptParseVtbl VBScriptParseVtbl = { @@ -782,7 +782,7 @@ static HRESULT WINAPI VBScriptParseProcedure_ParseProcedureText(IActiveScriptPar if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED;
- hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code); + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, dwFlags, &code); if(FAILED(hres)) return hres;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 2d78d5a..c9018c4 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -270,6 +270,7 @@ typedef enum { X(or, 1, 0, 0) \ X(pop, 1, ARG_UINT, 0) \ X(ret, 0, 0, 0) \ + X(retval, 1, 0, 0) \ X(set_ident, 1, ARG_BSTR, ARG_UINT) \ X(set_member, 1, ARG_BSTR, ARG_UINT) \ X(step, 0, ARG_ADDR, ARG_BSTR) \ @@ -353,7 +354,7 @@ struct _vbscode_t { };
void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN; -HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN; +HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,vbscode_t**) DECLSPEC_HIDDEN; HRESULT exec_script(script_ctx_t*,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN; void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN; IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/vbscript/tests/run.c | 151 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 6 deletions(-)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index f10a42b..1159daa 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -1792,7 +1792,7 @@ static IActiveScript *create_script(void) return script; }
-static IActiveScript *create_and_init_script(DWORD flags) +static IActiveScript *create_and_init_script(DWORD flags, BOOL start) { IActiveScriptParse *parser; IActiveScript *engine; @@ -1817,8 +1817,11 @@ static IActiveScript *create_and_init_script(DWORD flags) SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags); ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
- hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); - ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres); + if (start) + { + hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres); + }
return engine; } @@ -1843,7 +1846,7 @@ static HRESULT parse_script(DWORD flags, BSTR script_str, const WCHAR *delim) LONG ref; HRESULT hres;
- engine = create_and_init_script(flags); + engine = create_and_init_script(flags, TRUE); if(!engine) return S_OK;
@@ -1907,7 +1910,7 @@ static void test_parse_context(void) static const WCHAR yW[] = {'y',0};
global_ref = 1; - engine = create_and_init_script(0); + engine = create_and_init_script(0, TRUE); if(!engine) return;
@@ -2004,7 +2007,7 @@ static void test_procedures(void) VARIANT v; HRESULT hres;
- script = create_and_init_script(0); + script = create_and_init_script(0, TRUE);
hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc); ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres); @@ -2239,6 +2242,141 @@ static HRESULT test_global_vars_ref(BOOL use_close) return hres; }
+static void test_isexpression(void) +{ + IActiveScriptParse *parser; + IActiveScript *engine; + SCRIPTSTATE ss; + HRESULT hres; + VARIANT var; + BSTR str; + + if (!(engine = create_and_init_script(0, FALSE))) + return; + + hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres); + if (FAILED(hres)) + { + close_script(engine); + return; + } + + /* Expression when script is not started is still executed */ + hres = IActiveScript_GetScriptState(engine, &ss); + ok(hres == S_OK, "GetScriptState failed: %08x\n", hres); + ok(ss == SCRIPTSTATE_INITIALIZED, "Wrong script state %u\n", ss); + + str = a2bstr("13"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var)); + ok(V_I2(&var) == 13, "Expected 13, got %d\n", V_I2(&var)); + VariantClear(&var); + SysFreeString(str); + + hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres); + + /* Empty expressions */ + V_VT(&var) = VT_I2; + str = a2bstr(""); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_EMPTY, "Expected VT_EMPTY, got %s\n", vt2a(&var)); + VariantClear(&var); + SysFreeString(str); + + /* Two expressions fail */ + str = a2bstr("1\n3"); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(FAILED(hres), "ParseScriptText did not fail: %08x\n", hres); + todo_wine CHECK_CALLED(OnScriptError); + VariantClear(&var); + SysFreeString(str); + + /* Simple numerical expression */ + str = a2bstr("(1 + 7) * 2 - 3"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var)); + ok(V_I2(&var) == 13, "Expected 13, got %d\n", V_I2(&var)); + VariantClear(&var); + SysFreeString(str); + + /* An expression can also refer to a variable, function, class, etc previously set */ + V_VT(&var) = VT_I2; + str = a2bstr("If True Then foo = 42 Else foo = 0\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_EMPTY, "Expected VT_EMPTY, got %s\n", vt2a(&var)); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("foo\n\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var)); + ok(V_I2(&var) == 42, "Expected 42, got %d\n", V_I2(&var)); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("foo : "); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(FAILED(hres), "ParseScriptText did not fail: %08x\n", hres); + todo_wine CHECK_CALLED(OnScriptError); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr(""foo is " & CStr(foo) \n \n\n "); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&var)); + ok(!strcmp_wa(V_BSTR(&var), "foo is 42"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("Function test(x)\n" + " test = x + 0.5\n" + "End Function\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); + + str = a2bstr("test(4) * 3\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_R8, "Expected VT_R8, got %s\n", vt2a(&var)); + ok(V_R8(&var) == 13.5, "Expected %lf, got %lf\n", 13.5, V_R8(&var)); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("Class C\n" + " Public x\n" + "End Class\n" + "Set obj = New C\n" + "obj.x = True\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); + + str = a2bstr("obj.x"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_BOOL, "Expected VT_BOOL, got %s\n", vt2a(&var)); + ok(V_BOOL(&var) == VARIANT_TRUE, "Expected %x, got %x\n", VARIANT_TRUE, V_BOOL(&var)); + VariantClear(&var); + SysFreeString(str); + + IActiveScriptParse_Release(parser); + close_script(engine); +} + static BSTR get_script_from_file(const char *filename) { DWORD size, len; @@ -2556,6 +2694,7 @@ static void run_tests(void) test_procedures(); test_gc(); test_msgbox(); + test_isexpression(); test_parse_errors(); test_parse_context(); }
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Most of it works already due to implementing it in the compiler itself as an opcode. The only thing that's missing is to actually return the result.
dlls/vbscript/vbdisp.c | 2 +- include/activscp.idl | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index a907f40..0f6209f 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -626,7 +626,7 @@ static HRESULT Procedure_invoke(vbdisp_t *This, VARIANT *args, unsigned args_cnt TRACE("\n");
IActiveScriptSite_OnEnterScript(ctx->site); - hres = exec_script(ctx, This->desc->value_func, NULL, NULL, NULL); + hres = exec_script(ctx, This->desc->value_func, NULL, NULL, res); IActiveScriptSite_OnLeaveScript(ctx->site);
return hres; diff --git a/include/activscp.idl b/include/activscp.idl index 57179cf..97e7f5b 100644 --- a/include/activscp.idl +++ b/include/activscp.idl @@ -113,10 +113,12 @@ cpp_quote(" SCRIPTTEXT_ISVISIBLE | \") cpp_quote(" SCRIPTTEXT_ISEXPRESSION | \") cpp_quote(" SCRIPTTEXT_ISPERSISTENT | \") cpp_quote(" SCRIPTTEXT_HOSTMANAGESSOURCE)") +cpp_quote("#define SCRIPTPROC_ISEXPRESSION 0x00000020") cpp_quote("#define SCRIPTPROC_HOSTMANAGESSOURCE 0x00000080") cpp_quote("#define SCRIPTPROC_IMPLICIT_THIS 0x00000100") cpp_quote("#define SCRIPTPROC_IMPLICIT_PARENTS 0x00000200") -cpp_quote("#define SCRIPTPROC_ALL_FLAGS (SCRIPTPROC_HOSTMANAGESSOURCE | \") +cpp_quote("#define SCRIPTPROC_ALL_FLAGS (SCRIPTPROC_ISEXPRESSION | \") +cpp_quote(" SCRIPTPROC_HOSTMANAGESSOURCE | \") cpp_quote(" SCRIPTPROC_IMPLICIT_THIS | \") cpp_quote(" SCRIPTPROC_IMPLICIT_PARENTS)") cpp_quote("#define SCRIPTINFO_IUNKNOWN 0x00000001")
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/vbscript/tests/run.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 1159daa..8e51e3c 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -1973,7 +1973,7 @@ static void _parse_htmlscript_a(unsigned line, const char *src) ok_(__FILE__,line)(hres == S_OK, "parse_script failed: %08x\n", hres); }
-static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src) +static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src, DWORD flags) { IDispatchEx *dispex; IDispatch *disp; @@ -1984,7 +1984,7 @@ static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, co
str = a2bstr(src); hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, emptyW, NULL, NULL, delimiterW, 0, 0, - SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp); + SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS|flags, &disp); SysFreeString(str); ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres); ok(disp != NULL, "disp = NULL\n"); @@ -2012,12 +2012,20 @@ static void test_procedures(void) hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc); ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
- proc = parse_procedure(parse_proc, "dim x\nif true then x=false"); + proc = parse_procedure(parse_proc, "dim x\nif true then x=false", 0);
V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + VariantClear(&v); + IDispatchEx_Release(proc);
+ proc = parse_procedure(parse_proc, ""foobar"", SCRIPTPROC_ISEXPRESSION); + hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&v)); + ok(!strcmp_wa(V_BSTR(&v), "foobar"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); IDispatchEx_Release(proc);
IActiveScriptParseProcedure2_Release(parse_proc);
Signed-off-by: Jacek Caban jacek@codeweavers.com