Jacek Caban : vbscript: Added exit sub statement implementation.

Alexandre Julliard julliard at winehq.org
Wed Sep 14 12:25:40 CDT 2011


Module: wine
Branch: master
Commit: d04ba41aa97f5e00ca4b1e05ecbc520a6491343e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d04ba41aa97f5e00ca4b1e05ecbc520a6491343e

Author: Jacek Caban <jacek at 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)
 




More information about the wine-cvs mailing list