Jacek Caban : vbscript: Added exit for statement support.

Alexandre Julliard julliard at winehq.org
Thu Sep 22 13:39:48 CDT 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 22 14:24:44 2011 +0200

vbscript: Added exit for statement support.

---

 dlls/vbscript/compile.c      |   27 +++++++++++++++++++++++++--
 dlls/vbscript/parse.h        |    1 +
 dlls/vbscript/parser.y       |    1 +
 dlls/vbscript/tests/lang.vbs |    9 +++++++++
 4 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 1f1f041..153e9b0 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -39,6 +39,7 @@ typedef struct {
     unsigned labels_cnt;
 
     unsigned while_end_label;
+    unsigned for_end_label;
     unsigned sub_end_label;
     unsigned func_end_label;
     unsigned prop_end_label;
@@ -617,7 +618,7 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
 
 static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
 {
-    unsigned step_instr, instr;
+    unsigned step_instr, instr, prev_label;
     BSTR identifier;
     HRESULT hres;
 
@@ -654,10 +655,16 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
             return hres;
     }
 
+    prev_label = ctx->for_end_label;
+    ctx->for_end_label = alloc_label(ctx);
+    if(ctx->for_end_label == -1)
+        return E_OUTOFMEMORY;
+
     step_instr = push_instr(ctx, OP_step);
     if(step_instr == -1)
         return E_OUTOFMEMORY;
     instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
+    instr_ptr(ctx, step_instr)->arg1.uint = ctx->for_end_label;
 
     hres = compile_statement(ctx, stat->body);
     if(FAILED(hres))
@@ -672,7 +679,8 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
     if(FAILED(hres))
         return hres;
 
-    instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
+    label_set_addr(ctx, ctx->for_end_label);
+    ctx->for_end_label = prev_label;
 
     return push_instr_uint(ctx, OP_pop, 2);
 }
@@ -804,6 +812,16 @@ static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
     return push_instr_addr(ctx, OP_jmp, ctx->while_end_label);
 }
 
+static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
+{
+    if(ctx->for_end_label == -1) {
+        FIXME("Exit For outside For Loop\n");
+        return E_FAIL;
+    }
+
+    return push_instr_addr(ctx, OP_jmp, ctx->for_end_label);
+}
+
 static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
 {
     if(ctx->sub_end_label == -1) {
@@ -864,6 +882,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
         case STAT_EXITDO:
             hres = compile_exitdo_statement(ctx);
             break;
+        case STAT_EXITFOR:
+            hres = compile_exitfor_statement(ctx);
+            break;
         case STAT_EXITFUNC:
             hres = compile_exitfunc_statement(ctx);
             break;
@@ -931,6 +952,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
     func->code_off = ctx->instr_cnt;
 
     ctx->while_end_label = -1;
+    ctx->for_end_label = -1;
     ctx->sub_end_label = -1;
     ctx->func_end_label = -1;
     ctx->prop_end_label = -1;
@@ -967,6 +989,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
         return hres;
 
     assert(ctx->while_end_label == -1);
+    assert(ctx->for_end_label == -1);
 
     if(ctx->sub_end_label != -1)
         label_set_addr(ctx, ctx->sub_end_label);
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index a5bd505..e58e7f3 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -103,6 +103,7 @@ typedef enum {
     STAT_DOUNTIL,
     STAT_DOWHILE,
     STAT_EXITDO,
+    STAT_EXITFOR,
     STAT_EXITFUNC,
     STAT_EXITPROP,
     STAT_EXITSUB,
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 3b30051..d6bda55 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -178,6 +178,7 @@ SimpleStatement
                                               CHECK_ERROR; }
     | FunctionDecl                          { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
     | tEXIT tDO                             { $$ = new_statement(ctx, STAT_EXITDO, 0); CHECK_ERROR; }
+    | tEXIT tFOR                            { $$ = new_statement(ctx, STAT_EXITFOR, 0); CHECK_ERROR; }
     | tEXIT tFUNCTION                       { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
     | tEXIT tPROPERTY                       { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; }
     | tEXIT tSUB                            { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 3b3ad50..46a0330 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -387,6 +387,15 @@ for x = 5 to 8
 next
 Call ok(y = "for8: 5 7", "y = " & y)
 
+for x = 1.5 to 1
+    Call ok(false, "for..to called when unexpected")
+next
+
+for x = 1 to 100
+    exit for
+    Call ok(false, "exit for not escaped the loop?")
+next
+
 if false then
 Sub testsub
     x = true




More information about the wine-cvs mailing list