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:
parent
74ab018763
commit
e8b2f85bb1
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue