Module: wine Branch: master Commit: d04ba41aa97f5e00ca4b1e05ecbc520a6491343e URL: http://source.winehq.org/git/wine.git/?a=commit;h=d04ba41aa97f5e00ca4b1e05ec...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Sep 14 12:57:27 2011 +0200
vbscript: Added exit sub statement implementation.
---
dlls/vbscript/compile.c | 30 ++++++++++++++++++++++++++++++ dlls/vbscript/parse.h | 1 + dlls/vbscript/parser.y | 6 ++++-- dlls/vbscript/tests/lang.vbs | 9 +++++++++ 4 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 386caf7..84a97a7 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -38,6 +38,8 @@ typedef struct { unsigned labels_size; unsigned labels_cnt;
+ unsigned sub_end_label; + dim_decl_t *dim_decls; dynamic_var_t *global_vars;
@@ -530,6 +532,16 @@ static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement return S_OK; }
+static HRESULT compile_exitsub_statement(compile_ctx_t *ctx) +{ + if(ctx->sub_end_label == -1) { + FIXME("Exit Sub outside Sub?\n"); + return E_FAIL; + } + + return push_instr_addr(ctx, OP_jmp, ctx->sub_end_label); +} + static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) { HRESULT hres; @@ -545,6 +557,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_EXITSUB: + hres = compile_exitsub_statement(ctx); + break; case STAT_FUNC: hres = compile_function_statement(ctx, (function_statement_t*)stat); break; @@ -585,6 +600,18 @@ 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; + + switch(func->type) { + case FUNC_SUB: + ctx->sub_end_label = alloc_label(ctx); + if(ctx->sub_end_label == -1) + return E_OUTOFMEMORY; + break; + case FUNC_GLOBAL: + break; + } + ctx->func = func; ctx->dim_decls = NULL; hres = compile_statement(ctx, stat); @@ -592,6 +619,9 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f if(FAILED(hres)) return hres;
+ if(ctx->sub_end_label != -1) + label_set_addr(ctx, ctx->sub_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 9b837c2..69eca61 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -86,6 +86,7 @@ typedef enum { STAT_ASSIGN, STAT_CALL, STAT_DIM, + STAT_EXITSUB, STAT_FUNC, STAT_IF } statement_type_t; diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 4964d71..f406f8e 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -45,6 +45,7 @@ static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expre
static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
+static void *new_statement(parser_ctx_t*,statement_type_t,size_t); static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*); static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*); static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*); @@ -138,6 +139,7 @@ Statement | tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; } | IfStatement { $$ = $1; } | FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; } + | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
MemberExpression : tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } @@ -388,11 +390,11 @@ static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_ return expr; }
-static void *new_statement(parser_ctx_t *ctx, statement_type_t type, unsigned size) +static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size) { statement_t *stat;
- stat = parser_alloc(ctx, size); + stat = parser_alloc(ctx, size ? size : sizeof(*stat)); if(stat) { stat->type = type; stat->next = NULL; diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 100f93b..1140326 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -218,6 +218,15 @@ Sub TestSubMultiArgs(a,b,c,d,e) Call ok(e=5, "e = " & e) End Sub
+Sub TestSubExit(ByRef a) + If a Then + Exit Sub + End If + Call ok(false, "Exit Sub not called?") +End Sub + +Call TestSubExit(true) + TestSubMultiArgs 1, 2, 3, 4, 5 Call TestSubMultiArgs(1, 2, 3, 4, 5)