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