Commit e8b2f85b authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

vbscript: Add support for interpreting statements.

parent 74ab0187
......@@ -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;
......
......@@ -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);
......
......@@ -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) \
......
......@@ -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"
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment