Module: wine Branch: master Commit: e8b2f85bb1d37401f799eeb4a722052718bf8221 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e8b2f85bb1d37401f799eeb4a...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Oct 29 19:01:23 2019 +0100
vbscript: Add support for interpreting statements.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/vbscript/compile.c | 41 +++++++++++++++++++++++++++++++++++++++++ dlls/vbscript/interp.c | 20 ++++++++++++++++++++ dlls/vbscript/vbscript.h | 1 + dlls/vbscript/vbscript.rc | 1 + dlls/vbscript/vbscript_defs.h | 1 + 5 files changed, 64 insertions(+)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 2023261399..07279794c6 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -32,6 +32,7 @@ typedef struct _statement_ctx_t {
unsigned while_end_label; unsigned for_end_label; + unsigned with_stack_offset;
struct _statement_ctx_t *next; } statement_ctx_t; @@ -475,6 +476,21 @@ static HRESULT compile_call_expression(compile_ctx_t *ctx, call_expression_t *ex return push_instr_uint(ctx, ret_val ? OP_vcall : OP_vcallv, arg_cnt); }
+static HRESULT compile_dot_expression(compile_ctx_t *ctx) +{ + statement_ctx_t *stat_ctx; + + for(stat_ctx = ctx->stat_ctx; stat_ctx; stat_ctx = stat_ctx->next) { + if(!stat_ctx->with_stack_offset) + continue; + + return push_instr_uint(ctx, OP_stack, stat_ctx->with_stack_offset - 1); + } + + WARN("dot expression outside with statement\n"); + return push_instr_uint(ctx, OP_stack, ~0); +} + static HRESULT compile_unary_expression(compile_ctx_t *ctx, unary_expression_t *expr, vbsop_t op) { HRESULT hres; @@ -518,6 +534,8 @@ static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr) return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat); case EXPR_DIV: return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div); + case EXPR_DOT: + return compile_dot_expression(ctx); case EXPR_DOUBLE: return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value); case EXPR_EMPTY: @@ -858,6 +876,26 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st return S_OK; }
+static HRESULT compile_with_statement(compile_ctx_t *ctx, with_statement_t *stat) +{ + statement_ctx_t with_ctx = { 1 }; + HRESULT hres; + + hres = compile_expression(ctx, stat->expr); + if(FAILED(hres)) + return hres; + + if(!emit_catch(ctx, 1)) + return E_OUTOFMEMORY; + + with_ctx.with_stack_offset = stack_offset(ctx) + 1; + hres = compile_statement(ctx, &with_ctx, stat->body); + if(FAILED(hres)) + return hres; + + return push_instr_uint(ctx, OP_pop, 1); +} + static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat) { unsigned end_label, case_cnt = 0, *case_labels = NULL, i; @@ -1320,6 +1358,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_WITH: + hres = compile_with_statement(ctx, (with_statement_t*)stat); + break; case STAT_RETVAL: hres = compile_retval_statement(ctx, (retval_statement_t*)stat); break; diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 60c4340d6e..2b681a0677 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -1028,6 +1028,26 @@ static HRESULT interp_pop(exec_ctx_t *ctx) return S_OK; }
+static HRESULT interp_stack(exec_ctx_t *ctx) +{ + const unsigned n = ctx->instr->arg1.uint; + VARIANT v; + HRESULT hres; + + TRACE("%#x\n", n); + + if(n == ~0) + return MAKE_VBSERROR(505); + assert(n < ctx->top); + + V_VT(&v) = VT_EMPTY; + hres = VariantCopy(&v, ctx->stack + n); + if(FAILED(hres)) + return hres; + + return stack_push(ctx, &v); +} + static HRESULT interp_deref(exec_ctx_t *ctx) { VARIANT copy, *v = stack_top(ctx, 0); diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 33eb1e8305..fefed63edb 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -267,6 +267,7 @@ typedef enum { X(retval, 1, 0, 0) \ X(set_ident, 1, ARG_BSTR, ARG_UINT) \ X(set_member, 1, ARG_BSTR, ARG_UINT) \ + X(stack, 1, ARG_UINT, 0) \ X(step, 0, ARG_ADDR, ARG_BSTR) \ X(stop, 1, 0, 0) \ X(string, 1, ARG_STR, 0) \ diff --git a/dlls/vbscript/vbscript.rc b/dlls/vbscript/vbscript.rc index 360b1006d6..0791c3b53f 100644 --- a/dlls/vbscript/vbscript.rc +++ b/dlls/vbscript/vbscript.rc @@ -54,6 +54,7 @@ STRINGTABLE VBSE_INVALID_DLL_FUNCTION_NAME "Specified DLL function not found" VBSE_INVALID_TYPELIB_VARIABLE "Variable uses an Automation type not supported in VBScript" VBSE_SERVER_NOT_FOUND "The remote server machine does not exist or is unavailable" + VBSE_UNQUALIFIED_REFERENCE "Invalid or unqualified reference"
VBS_COMPILE_ERROR "Microsoft VBScript compilation error" VBS_RUNTIME_ERROR "Microsoft VBScript runtime error" diff --git a/dlls/vbscript/vbscript_defs.h b/dlls/vbscript/vbscript_defs.h index 44f005b640..139b71255a 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -267,6 +267,7 @@ #define VBSE_INVALID_DLL_FUNCTION_NAME 453 #define VBSE_INVALID_TYPELIB_VARIABLE 458 #define VBSE_SERVER_NOT_FOUND 462 +#define VBSE_UNQUALIFIED_REFERENCE 505
#define VBS_COMPILE_ERROR 4096 #define VBS_RUNTIME_ERROR 4097