From 1cefcdb6b7085f23c17dcddd1e928ec26ebd867b Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 14 Sep 2011 12:58:10 +0200 Subject: [PATCH] vbscript: Added Exit Function statement implementation. --- dlls/vbscript/compile.c | 23 ++++++++++++++++++++++- dlls/vbscript/parse.h | 1 + dlls/vbscript/parser.y | 1 + dlls/vbscript/tests/lang.vbs | 9 +++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index a4608bed749..21b50bdf4f7 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -39,6 +39,7 @@ typedef struct { unsigned labels_cnt; unsigned sub_end_label; + unsigned func_end_label; dim_decl_t *dim_decls; dynamic_var_t *global_vars; @@ -555,6 +556,16 @@ static HRESULT compile_exitsub_statement(compile_ctx_t *ctx) return push_instr_addr(ctx, OP_jmp, ctx->sub_end_label); } +static HRESULT compile_exitfunc_statement(compile_ctx_t *ctx) +{ + if(ctx->func_end_label == -1) { + FIXME("Exit Function outside Function?\n"); + return E_FAIL; + } + + return push_instr_addr(ctx, OP_jmp, ctx->func_end_label); +} + static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) { HRESULT hres; @@ -570,6 +581,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) case STAT_DIM: hres = compile_dim_statement(ctx, (dim_statement_t*)stat); break; + case STAT_EXITFUNC: + hres = compile_exitfunc_statement(ctx); + break; case STAT_EXITSUB: hres = compile_exitsub_statement(ctx); break; @@ -614,14 +628,19 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f func->code_off = ctx->instr_cnt; ctx->sub_end_label = -1; + ctx->func_end_label = -1; switch(func->type) { + case FUNC_FUNCTION: + ctx->func_end_label = alloc_label(ctx); + if(ctx->func_end_label == -1) + return E_OUTOFMEMORY; /* FIXME ! */ + break; case FUNC_SUB: ctx->sub_end_label = alloc_label(ctx); if(ctx->sub_end_label == -1) return E_OUTOFMEMORY; break; - case FUNC_FUNCTION: /* FIXME */ case FUNC_GLOBAL: break; } @@ -635,6 +654,8 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f if(ctx->sub_end_label != -1) label_set_addr(ctx, ctx->sub_end_label); + if(ctx->func_end_label != -1) + label_set_addr(ctx, ctx->func_end_label); if(push_instr(ctx, OP_ret) == -1) return E_OUTOFMEMORY; diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 69eca6126b3..6406fc2ed32 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -86,6 +86,7 @@ typedef enum { STAT_ASSIGN, STAT_CALL, STAT_DIM, + STAT_EXITFUNC, STAT_EXITSUB, STAT_FUNC, STAT_IF diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 36edc02302b..870a6654d9f 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -139,6 +139,7 @@ Statement | tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; } | IfStatement { $$ = $1; } | FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; } + | tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; } | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; } MemberExpression diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 5f473608f61..93af6b66155 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -304,4 +304,13 @@ y = true Call TestFuncLocalVal Call ok(x, "global x is not true?") +Function TestFuncExit(ByRef a) + If a Then + Exit Function + End If + Call ok(false, "Exit Function not called?") +End Function + +Call TestFuncExit(true) + reportSuccess()