Jacek Caban : vbscript: Added Exit Function statement implementation.

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


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

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




More information about the wine-cvs mailing list