vbscript: Add support for interpreting statements.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-10-29 19:01:23 +01:00 committed by Alexandre Julliard
parent 74ab018763
commit e8b2f85bb1
5 changed files with 64 additions and 0 deletions

View File

@ -32,6 +32,7 @@ typedef struct _statement_ctx_t {
unsigned while_end_label; unsigned while_end_label;
unsigned for_end_label; unsigned for_end_label;
unsigned with_stack_offset;
struct _statement_ctx_t *next; struct _statement_ctx_t *next;
} statement_ctx_t; } 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); 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) static HRESULT compile_unary_expression(compile_ctx_t *ctx, unary_expression_t *expr, vbsop_t op)
{ {
HRESULT hres; 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); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat);
case EXPR_DIV: case EXPR_DIV:
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
case EXPR_DOT:
return compile_dot_expression(ctx);
case EXPR_DOUBLE: case EXPR_DOUBLE:
return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value); return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
case EXPR_EMPTY: case EXPR_EMPTY:
@ -858,6 +876,26 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
return S_OK; 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) static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
{ {
unsigned end_label, case_cnt = 0, *case_labels = NULL, i; 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: case STAT_WHILELOOP:
hres = compile_while_statement(ctx, (while_statement_t*)stat); hres = compile_while_statement(ctx, (while_statement_t*)stat);
break; break;
case STAT_WITH:
hres = compile_with_statement(ctx, (with_statement_t*)stat);
break;
case STAT_RETVAL: case STAT_RETVAL:
hres = compile_retval_statement(ctx, (retval_statement_t*)stat); hres = compile_retval_statement(ctx, (retval_statement_t*)stat);
break; break;

View File

@ -1028,6 +1028,26 @@ static HRESULT interp_pop(exec_ctx_t *ctx)
return S_OK; 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) static HRESULT interp_deref(exec_ctx_t *ctx)
{ {
VARIANT copy, *v = stack_top(ctx, 0); VARIANT copy, *v = stack_top(ctx, 0);

View File

@ -267,6 +267,7 @@ typedef enum {
X(retval, 1, 0, 0) \ X(retval, 1, 0, 0) \
X(set_ident, 1, ARG_BSTR, ARG_UINT) \ X(set_ident, 1, ARG_BSTR, ARG_UINT) \
X(set_member, 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(step, 0, ARG_ADDR, ARG_BSTR) \
X(stop, 1, 0, 0) \ X(stop, 1, 0, 0) \
X(string, 1, ARG_STR, 0) \ X(string, 1, ARG_STR, 0) \

View File

@ -54,6 +54,7 @@ STRINGTABLE
VBSE_INVALID_DLL_FUNCTION_NAME "Specified DLL function not found" VBSE_INVALID_DLL_FUNCTION_NAME "Specified DLL function not found"
VBSE_INVALID_TYPELIB_VARIABLE "Variable uses an Automation type not supported in VBScript" 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_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_COMPILE_ERROR "Microsoft VBScript compilation error"
VBS_RUNTIME_ERROR "Microsoft VBScript runtime error" VBS_RUNTIME_ERROR "Microsoft VBScript runtime error"

View File

@ -267,6 +267,7 @@
#define VBSE_INVALID_DLL_FUNCTION_NAME 453 #define VBSE_INVALID_DLL_FUNCTION_NAME 453
#define VBSE_INVALID_TYPELIB_VARIABLE 458 #define VBSE_INVALID_TYPELIB_VARIABLE 458
#define VBSE_SERVER_NOT_FOUND 462 #define VBSE_SERVER_NOT_FOUND 462
#define VBSE_UNQUALIFIED_REFERENCE 505
#define VBS_COMPILE_ERROR 4096 #define VBS_COMPILE_ERROR 4096
#define VBS_RUNTIME_ERROR 4097 #define VBS_RUNTIME_ERROR 4097