Module: wine Branch: master Commit: 1cefcdb6b7085f23c17dcddd1e928ec26ebd867b URL: http://source.winehq.org/git/wine.git/?a=commit;h=1cefcdb6b7085f23c17dcddd1e...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Sep 14 12:58:10 2011 +0200
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 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index a4608be..21b50bd 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 69eca61..6406fc2 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 36edc02..870a665 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 5f47360..93af6b6 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()