78838: Subject: [PATCH 07/21] vbscript: Added interpreter support for sub arguments

buildbot at kegel.com buildbot at kegel.com
Wed Sep 14 08:41:36 CDT 2011


This is an experimental automated build and test service.
Please feel free to ignore this email while we work the kinks out.

For more info about this message, see http://wiki.winehq.org/BuildBot

The Buildbot has detected a failed build on builder runtests-heaptest while building Wine.
Full details are available at: http://buildbot.kegel.com/builders/runtests-heaptest/builds/31 (though maybe not for long, as I'm still reinstalling the buildbot periodically while experimenting)
BUILD FAILED: failed shell_3

Errors:


-------------- next part --------------
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 01/21] vbscript: Added sub statement parser implementation
Message-Id: <4E7087FA.4090207 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:54:50 +0200

---
  dlls/vbscript/parse.h    |   24 +++++++++++++-
  dlls/vbscript/parser.y   |   75 
++++++++++++++++++++++++++++++++++++++++++++-
  dlls/vbscript/vbscript.h |    5 +++
  3 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index cfeb8c0..9b837c2 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -85,8 +85,9 @@ typedef struct {
 typedef enum {
     STAT_ASSIGN,
     STAT_CALL,
-    STAT_IF,
-    STAT_DIM
+    STAT_DIM,
+    STAT_FUNC,
+    STAT_IF
 } statement_type_t;
 
 typedef struct _statement_t {
@@ -115,6 +116,25 @@ typedef struct _dim_statement_t {
     dim_decl_t *dim_decls;
 } dim_statement_t;
 
+typedef struct _arg_decl_t {
+    const WCHAR *name;
+    BOOL by_ref;
+    struct _arg_decl_t *next;
+} arg_decl_t;
+
+typedef struct _function_decl_t {
+    const WCHAR *name;
+    function_type_t type;
+    arg_decl_t *args;
+    statement_t *body;
+    struct _function_decl_t *next;
+} function_decl_t;
+
+typedef struct _function_statement_t {
+    statement_t stat;
+    function_decl_t *func_decl;
+} function_statement_t;
+
 typedef struct _elseif_decl_t {
     expression_t *expr;
     statement_t *stat;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index c9f9c76..4964d71 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -48,10 +48,13 @@ static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,co
 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*);
- static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
+static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
+static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
 
 static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
 static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
+static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,arg_decl_t*,statement_t*);
+static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
 
 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
 
@@ -67,6 +70,8 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
     member_expression_t *member;
     elseif_decl_t *elseif;
     dim_decl_t *dim_decl;
+    function_decl_t *func_decl;
+    arg_decl_t *arg_decl;
     LONG lng;
     BOOL bool;
     double dbl;
@@ -89,13 +94,15 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
 %token <lng> tLong tShort
 %token <dbl> tDouble
 
-%type <statement> Statement StatementNl StatementsNl IfStatement Else_opt
+%type <statement> Statement StatementNl StatementsNl StatementsNl_opt IfStatement Else_opt
 %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression
 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
 %type <expression> NotExpression UnaryExpression
 %type <member> MemberExpression
 %type <expression> Arguments_opt ArgumentList_opt ArgumentList
 %type <bool> OptionExplicit_opt
+%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
+%type <func_decl> FunctionDecl
 %type <elseif> ElseIfs_opt ElseIfs ElseIf
 %type <dim_decl> DimDeclList
 
@@ -112,6 +119,10 @@ SourceElements
     : /* empty */
     | SourceElements StatementNl    { source_add_statement(ctx, $2); }
 
+StatementsNl_opt
+    : /* empty */                           { $$ = NULL; }
+    | StatementsNl                          { $$ = $1; }
+
 StatementsNl
     : StatementNl                           { $$ = $1; }
     | StatementNl StatementsNl              { $1->next = $2; $$ = $1; }
@@ -126,6 +137,7 @@ Statement
                                             { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
     | tDIM DimDeclList                      { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
     | IfStatement                           { $$ = $1; }
+    | FunctionDecl                          { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
 
 MemberExpression
     : tIdentifier                           { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
@@ -236,6 +248,23 @@ LiteralExpression
 PrimaryExpression
     : '(' Expression ')'            { $$ = $2; }
 
+FunctionDecl
+    : /* Storage_opt */ tSUB tIdentifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tSUB
+                                    { $$ = new_function_decl(ctx, $2, FUNC_SUB, $3, $5); CHECK_ERROR; }
+
+ArgumentsDecl_opt
+    : EmptyBrackets_opt                         { $$ = NULL; }
+    | '(' ArgumentDeclList ')'                  { $$ = $2; }
+
+ArgumentDeclList
+    : ArgumentDecl                              { $$ = $1; }
+    | ArgumentDecl ',' ArgumentDeclList         { $1->next = $3; $$ = $1; }
+
+ArgumentDecl
+    : tIdentifier                               { $$ = new_argument_decl(ctx, $1, TRUE); }
+    | tBYREF tIdentifier                        { $$ = new_argument_decl(ctx, $2, TRUE); }
+    | tBYVAL tIdentifier                        { $$ = new_argument_decl(ctx, $2, FALSE); }
+
 %%
 
 static int parser_error(const char *str)
@@ -452,6 +481,48 @@ static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, stat
     return &stat->stat;
 }
 
+static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL by_ref)
+{
+    arg_decl_t *arg_decl;
+
+    arg_decl = parser_alloc(ctx, sizeof(*arg_decl));
+    if(!arg_decl)
+        return NULL;
+
+    arg_decl->name = name;
+    arg_decl->by_ref = by_ref;
+    arg_decl->next = NULL;
+    return arg_decl;
+}
+
+static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type,
+        arg_decl_t *arg_decl, statement_t *body)
+{
+    function_decl_t *decl;
+
+    decl = parser_alloc(ctx, sizeof(*decl));
+    if(!decl)
+        return NULL;
+
+    decl->name = name;
+    decl->type = type;
+    decl->args = arg_decl;
+    decl->body = body;
+    return decl;
+}
+
+static statement_t *new_function_statement(parser_ctx_t *ctx, function_decl_t *decl)
+{
+    function_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_FUNC, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->func_decl = decl;
+    return &stat->stat;
+}
+
 void *parser_alloc(parser_ctx_t *ctx, size_t size)
 {
     void *ret;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index afa9d83..b52aa09 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -146,6 +146,11 @@ typedef struct {
     instr_arg_t arg2;
 } instr_t;
 
+typedef enum {
+    FUNC_GLOBAL,
+    FUNC_SUB
+} function_type_t;
+
 struct _function_t {
     unsigned code_off;
     vbscode_t *code_ctx;

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 02/21] vbscript: Added function compiler implementation
Message-Id: <4E70880B.8010305 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:55:07 +0200

---
  dlls/vbscript/compile.c      |  142 
+++++++++++++++++++++++++++++++++++------
  dlls/vbscript/tests/lang.vbs |    6 ++
  dlls/vbscript/vbscript.h     |    3 +
  3 files changed, 130 insertions(+), 21 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index d39b94e..4e8cd06 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -40,6 +40,10 @@ typedef struct {
 
     dim_decl_t *dim_decls;
     dynamic_var_t *global_vars;
+
+    function_t *func;
+    function_t *funcs;
+    function_decl_t *func_decls;
 } compile_ctx_t;
 
 static HRESULT compile_expression(compile_ctx_t*,expression_t*);
@@ -514,6 +518,18 @@ static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
     return S_OK;
 }
 
+static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
+{
+    if(ctx->func != &ctx->code->global_code) {
+        FIXME("Function is not in the global code\n");
+        return E_FAIL;
+    }
+
+    stat->func_decl->next = ctx->func_decls;
+    ctx->func_decls = stat->func_decl;
+    return S_OK;
+}
+
 static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
 {
     HRESULT hres;
@@ -529,6 +545,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_FUNC:
+            hres = compile_function_statement(ctx, (function_statement_t*)stat);
+            break;
         case STAT_IF:
             hres = compile_if_statement(ctx, (if_statement_t*)stat);
             break;
@@ -545,11 +564,11 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
     return S_OK;
 }
 
-static void resolve_labels(compile_ctx_t *ctx)
+static void resolve_labels(compile_ctx_t *ctx, unsigned off)
 {
     instr_t *instr;
 
-    for(instr = ctx->code->instrs; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
+    for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
         if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->arg1.uint & LABEL_FLAG)) {
             assert((instr->arg1.uint & ~LABEL_FLAG) < ctx->labels_cnt);
             instr->arg1.uint = ctx->labels[instr->arg1.uint & ~LABEL_FLAG];
@@ -566,38 +585,92 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f
 
     func->code_off = ctx->instr_cnt;
 
+    ctx->func = func;
+    ctx->dim_decls = NULL;
     hres = compile_statement(ctx, stat);
+    ctx->func = NULL;
     if(FAILED(hres))
         return hres;
 
     if(push_instr(ctx, OP_ret) == -1)
         return E_OUTOFMEMORY;
 
-    resolve_labels(ctx);
+    resolve_labels(ctx, func->code_off);
 
     if(ctx->dim_decls) {
         dim_decl_t *dim_decl;
-        dynamic_var_t *new_var;
 
-        for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
-            new_var = compiler_alloc(ctx->code, sizeof(*new_var));
-            if(!new_var)
-                return E_OUTOFMEMORY;
+        if(func->type == FUNC_GLOBAL) {
+            dynamic_var_t *new_var;
 
-            new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
-            if(!new_var->name)
-                return E_OUTOFMEMORY;
+            for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
+                new_var = compiler_alloc(ctx->code, sizeof(*new_var));
+                if(!new_var)
+                    return E_OUTOFMEMORY;
 
-            V_VT(&new_var->v) = VT_EMPTY;
+                new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
+                if(!new_var->name)
+                    return E_OUTOFMEMORY;
 
-            new_var->next = ctx->global_vars;
-            ctx->global_vars = new_var;
+                V_VT(&new_var->v) = VT_EMPTY;
+
+                new_var->next = ctx->global_vars;
+                ctx->global_vars = new_var;
+            }
+        }else {
+            FIXME("var not implemented for functions\n");
         }
     }
 
     return S_OK;
 }
 
+static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
+{
+    function_t *iter;
+
+    for(iter = ctx->funcs; iter; iter = iter->next) {
+        if(!strcmpiW(iter->name, name))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
+{
+    function_t *func;
+    HRESULT hres;
+
+    if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name)) {
+        FIXME("%s: redefinition\n", debugstr_w(decl->name));
+        return E_FAIL;
+    }
+
+    func = compiler_alloc(ctx->code, sizeof(*func));
+    if(!func)
+        return E_OUTOFMEMORY;
+
+    func->name = compiler_alloc_string(ctx->code, decl->name);
+    if(!func->name)
+        return E_OUTOFMEMORY;
+
+    func->code_ctx = ctx->code;
+    func->type = decl->type;
+
+    if(decl->args) {
+        FIXME("arguments not implemented\n");
+        return E_NOTIMPL;
+    }
+
+    hres = compile_func(ctx, decl->body, func);
+    if(FAILED(hres))
+        return hres;
+
+    *ret = func;
+    return S_OK;
+}
+
 static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
 {
     dynamic_var_t *var;
@@ -671,25 +744,40 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
     ret->bstr_pool_size = 0;
     ret->bstr_cnt = 0;
 
+    ret->global_code.type = FUNC_GLOBAL;
+    ret->global_code.name = NULL;
     ret->global_code.code_ctx = ret;
 
     list_init(&ret->entry);
     return ret;
 }
 
+static void release_compiler(compile_ctx_t *ctx)
+{
+    parser_release(&ctx->parser);
+    heap_free(ctx->labels);
+    if(ctx->code)
+        release_vbscode(ctx->code);
+}
+
 HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
 {
+    function_t *new_func;
+    function_decl_t *func_decl;
     compile_ctx_t ctx;
+    vbscode_t *code;
     HRESULT hres;
 
     hres = parse_script(&ctx.parser, src);
     if(FAILED(hres))
         return hres;
 
-    ctx.code = alloc_vbscode(&ctx, src);
+    code = ctx.code = alloc_vbscode(&ctx, src);
     if(!ctx.code)
         return E_OUTOFMEMORY;
 
+    ctx.funcs = NULL;
+    ctx.func_decls = NULL;
     ctx.global_vars = NULL;
     ctx.dim_decls = NULL;
     ctx.labels = NULL;
@@ -697,13 +785,24 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
 
     hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->global_code);
     if(FAILED(hres)) {
-        release_vbscode(ctx.code);
+        release_compiler(&ctx);
         return hres;
     }
 
+    for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
+        hres = create_function(&ctx, func_decl, &new_func);
+        if(FAILED(hres)) {
+            release_compiler(&ctx);
+            return hres;
+        }
+
+        new_func->next = ctx.funcs;
+        ctx.funcs = new_func;
+    }
+
     hres = check_script_collisions(&ctx, script);
     if(FAILED(hres)) {
-        release_vbscode(ctx.code);
+        release_compiler(&ctx);
         return hres;
     }
 
@@ -716,12 +815,13 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
         script->global_vars = ctx.global_vars;
     }
 
-    parser_release(&ctx.parser);
-
     if(TRACE_ON(vbscript_disas))
         dump_code(&ctx);
 
-    list_add_tail(&script->code_list, &ctx.code->entry);
-    *ret = ctx.code;
+    ctx.code = NULL;
+    release_compiler(&ctx);
+
+    list_add_tail(&script->code_list, &code->entry);
+    *ret = code;
     return S_OK;
 }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 12bdaf5..60ca988 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -169,4 +169,10 @@ ElseIf not False Then
 End If
 Call ok(x, "elseif not called?")
 
+if false then
+Sub testsub
+    x = true
+End Sub
+end if
+
 reportSuccess()
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index b52aa09..41dea38 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -152,8 +152,11 @@ typedef enum {
 } function_type_t;
 
 struct _function_t {
+    function_type_t type;
+    const WCHAR *name;
     unsigned code_off;
     vbscode_t *code_ctx;
+    function_t *next;
 };
 
 struct _vbscode_t {

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 03/21] vbscript: Store global functions in script_ctx_t
Message-Id: <4E708824.1060000 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:55:32 +0200

---
  dlls/vbscript/compile.c  |   21 +++++++++++++++++++++
  dlls/vbscript/vbscript.h |    1 +
  2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 4e8cd06..651bf7c 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -674,18 +674,25 @@ static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, functi
 static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
 {
     dynamic_var_t *var;
+    function_t *func;
 
     for(var = script->global_vars; var; var = var->next) {
         if(!strcmpiW(var->name, identifier))
             return TRUE;
     }
 
+    for(func = script->global_funcs; func; func = func->next) {
+        if(!strcmpiW(func->name, identifier))
+            return TRUE;
+    }
+
     return FALSE;
 }
 
 static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
 {
     dynamic_var_t *var;
+    function_t *func;
 
     for(var = ctx->global_vars; var; var = var->next) {
         if(lookup_script_identifier(script, var->name)) {
@@ -694,6 +701,13 @@ static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
         }
     }
 
+    for(func = ctx->funcs; func; func = func->next) {
+        if(lookup_script_identifier(script, func->name)) {
+            FIXME("%s: redefined\n", debugstr_w(func->name));
+            return E_FAIL;
+        }
+    }
+
     return S_OK;
 }
 
@@ -815,6 +829,13 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
         script->global_vars = ctx.global_vars;
     }
 
+    if(ctx.funcs) {
+        for(new_func = ctx.funcs; new_func->next; new_func = new_func->next);
+
+        new_func->next = script->global_funcs;
+        script->global_funcs = ctx.funcs;
+    }
+
     if(TRACE_ON(vbscript_disas))
         dump_code(&ctx);
 
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 41dea38..32b19ab 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -80,6 +80,7 @@ struct _script_ctx_t {
     vbdisp_t *script_obj;
 
     dynamic_var_t *global_vars;
+    function_t *global_funcs;
 
     struct list code_list;
     struct list named_items;

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 04/21] vbscript: Added functions lookup implementation
Message-Id: <4E70882E.90803 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:55:42 +0200

---
  dlls/vbscript/interp.c |   19 ++++++++++++++++++-
  1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 593c83e..25fd6bb 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -41,7 +41,8 @@ typedef HRESULT (*instr_func_t)(exec_ctx_t*);
 typedef enum {
     REF_NONE,
     REF_DISP,
-    REF_VAR
+    REF_VAR,
+    REF_FUNC
 } ref_type_t;
 
 typedef struct {
@@ -52,6 +53,7 @@ typedef struct {
             DISPID id;
         } d;
         VARIANT *v;
+        function_t *f;
     } u;
 } ref_t;
 
@@ -79,12 +81,21 @@ static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *re
 static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref)
 {
     named_item_t *item;
+    function_t *func;
     DISPID id;
     HRESULT hres;
 
     if(lookup_dynamic_vars(ctx->script->global_vars, name, ref))
         return S_OK;
 
+    for(func = ctx->script->global_funcs; func; func = func->next) {
+        if(!strcmpiW(func->name, name)) {
+            ref->type = REF_FUNC;
+            ref->u.f = func;
+            return S_OK;
+        }
+    }
+
     LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) {
         if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
             hres = disp_get_id(item->disp, name, &id);
@@ -254,6 +265,9 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
         if(FAILED(hres))
             return hres;
         break;
+    case REF_FUNC:
+        FIXME("functions not implemented\n");
+        return E_NOTIMPL;
     case REF_NONE:
         FIXME("%s not found\n", debugstr_w(identifier));
         return DISP_E_UNKNOWNNAME;
@@ -313,6 +327,9 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, VARIANT *val, BOOL own_v
         if(own_val)
             VariantClear(val);
         break;
+    case REF_FUNC:
+        FIXME("functions not implemented\n");
+        return E_NOTIMPL;
     case REF_NONE:
         FIXME("%s not found\n", debugstr_w(name));
         if(own_val)

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 05/21] vbscript: Added function invocation supprot to do_icall
Message-Id: <4E708841.7010503 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:56:01 +0200

---
  dlls/vbscript/interp.c       |   18 +++++++++++++++---
  dlls/vbscript/tests/lang.vbs |    4 ++++
  dlls/vbscript/vbscript.c     |    2 +-
  dlls/vbscript/vbscript.h     |    7 ++++++-
  4 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 25fd6bb..34d0d2f 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -266,8 +266,10 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
             return hres;
         break;
     case REF_FUNC:
-        FIXME("functions not implemented\n");
-        return E_NOTIMPL;
+        hres = exec_script(ctx->script, ref.u.f, &dp, res);
+        if(FAILED(hres))
+            return hres;
+        break;
     case REF_NONE:
         FIXME("%s not found\n", debugstr_w(identifier));
         return DISP_E_UNKNOWNNAME;
@@ -809,12 +811,22 @@ OP_LIST
 #undef X
 };
 
-HRESULT exec_script(script_ctx_t *ctx, function_t *func)
+HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT *res)
 {
     exec_ctx_t exec;
     vbsop_t op;
     HRESULT hres = S_OK;
 
+    if(res) {
+        FIXME("returning value is not implemented\n");
+        return E_NOTIMPL;
+    }
+
+    if(dp && arg_cnt(dp)) {
+        FIXME("arguments not implemented\n");
+        return E_NOTIMPL;
+    }
+
     exec.stack_size = 16;
     exec.top = 0;
     exec.stack = heap_alloc(exec.stack_size * sizeof(VARIANT));
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 60ca988..0c4c10f 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -175,4 +175,8 @@ Sub testsub
 End Sub
 end if
 
+x = false
+Call testsub
+Call ok(x, "x is false, testsub not called?")
+
 reportSuccess()
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index f6891c7..cb28a9a 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -77,7 +77,7 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code)
     code->global_executed = TRUE;
 
     IActiveScriptSite_OnEnterScript(ctx->site);
-    hres = exec_script(ctx, &code->global_code);
+    hres = exec_script(ctx, &code->global_code, NULL, NULL);
     IActiveScriptSite_OnLeaveScript(ctx->site);
 
     return hres;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 32b19ab..d541e9d 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -65,6 +65,11 @@ HRESULT disp_get_id(IDispatch*,BSTR,DISPID*);
 HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
 HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);
 
+static inline unsigned arg_cnt(const DISPPARAMS *dp)
+{
+    return dp->cArgs - dp->cNamedArgs;
+}
+
 typedef struct _dynamic_var_t {
     struct _dynamic_var_t *next;
     VARIANT v;
@@ -179,7 +184,7 @@ struct _vbscode_t {
 
 void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
 HRESULT compile_script(script_ctx_t*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
-HRESULT exec_script(script_ctx_t*,function_t*) DECLSPEC_HIDDEN;
+HRESULT exec_script(script_ctx_t*,function_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
 
 HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
 

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 06/21] vbscript: Added function arguments compiler implementation
Message-Id: <4E70885B.9010400 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:56:27 +0200

---
  dlls/vbscript/compile.c  |   23 +++++++++++++++++++++--
  dlls/vbscript/vbscript.h |    7 +++++++
  2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 651bf7c..bdff74d 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -658,9 +658,26 @@ static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, functi
     func->code_ctx = ctx->code;
     func->type = decl->type;
 
+    func->arg_cnt = 0;
     if(decl->args) {
-        FIXME("arguments not implemented\n");
-        return E_NOTIMPL;
+        arg_decl_t *arg;
+        unsigned i;
+
+        for(arg = decl->args; arg; arg = arg->next)
+            func->arg_cnt++;
+
+        func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t));
+        if(!func->args)
+            return E_OUTOFMEMORY;
+
+        for(i = 0, arg = decl->args; arg; arg = arg->next, i++) {
+            func->args[i].name = compiler_alloc_string(ctx->code, arg->name);
+            if(!func->args[i].name)
+                return E_OUTOFMEMORY;
+            func->args[i].by_ref = arg->by_ref;
+        }
+    }else {
+        decl->args = NULL;
     }
 
     hres = compile_func(ctx, decl->body, func);
@@ -761,6 +778,8 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
     ret->global_code.type = FUNC_GLOBAL;
     ret->global_code.name = NULL;
     ret->global_code.code_ctx = ret;
+    ret->global_code.arg_cnt = 0;
+    ret->global_code.args = NULL;
 
     list_init(&ret->entry);
     return ret;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index d541e9d..0e6d57e 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -152,6 +152,11 @@ typedef struct {
     instr_arg_t arg2;
 } instr_t;
 
+typedef struct {
+    const WCHAR *name;
+    BOOL by_ref;
+} arg_desc_t;
+
 typedef enum {
     FUNC_GLOBAL,
     FUNC_SUB
@@ -160,6 +165,8 @@ typedef enum {
 struct _function_t {
     function_type_t type;
     const WCHAR *name;
+    arg_desc_t *args;
+    unsigned arg_cnt;
     unsigned code_off;
     vbscode_t *code_ctx;
     function_t *next;

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 07/21] vbscript: Added interpreter support for sub arguments
Message-Id: <4E70886D.1080303 at codeweavers.com>
Date: Wed, 14 Sep 2011 12:56:45 +0200

---
  dlls/vbscript/interp.c   |   70 
+++++++++++++++++++++++++++++++++++++++++----
  dlls/vbscript/vbscript.h |    5 +++
  2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 34d0d2f..68fb4ed 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -31,6 +31,8 @@ typedef struct {
     script_ctx_t *script;
     function_t *func;
 
+    VARIANT *args;
+
     unsigned stack_size;
     unsigned top;
     VARIANT *stack;
@@ -82,9 +84,18 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref)
 {
     named_item_t *item;
     function_t *func;
+    unsigned i;
     DISPID id;
     HRESULT hres;
 
+    for(i=0; i < ctx->func->arg_cnt; i++) {
+        if(!strcmpiW(ctx->func->args[i].name, name)) {
+            ref->type = REF_VAR;
+            ref->u.v = ctx->args+i;
+            return S_OK;
+        }
+    }
+
     if(lookup_dynamic_vars(ctx->script->global_vars, name, ref))
         return S_OK;
 
@@ -811,9 +822,22 @@ OP_LIST
 #undef X
 };
 
+static void release_exec(exec_ctx_t *ctx)
+{
+    if(ctx->args) {
+        unsigned i;
+
+        for(i=0; i < ctx->func->arg_cnt; i++)
+            VariantClear(ctx->args+i);
+    }
+
+    heap_free(ctx->args);
+    heap_free(ctx->stack);
+}
+
 HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT *res)
 {
-    exec_ctx_t exec;
+    exec_ctx_t exec = {func->code_ctx};
     vbsop_t op;
     HRESULT hres = S_OK;
 
@@ -822,18 +846,50 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT
         return E_NOTIMPL;
     }
 
-    if(dp && arg_cnt(dp)) {
-        FIXME("arguments not implemented\n");
-        return E_NOTIMPL;
+    exec.code = func->code_ctx;
+
+    if(dp ? func->arg_cnt != arg_cnt(dp) : func->arg_cnt) {
+        FIXME("wrong arg_cnt %d, expected %d\n", dp ? arg_cnt(dp) : 0, func->arg_cnt);
+        return E_FAIL;
+    }
+
+    if(func->arg_cnt) {
+        VARIANT *v;
+        unsigned i;
+
+        exec.args = heap_alloc_zero(func->arg_cnt * sizeof(VARIANT));
+        if(!exec.args) {
+            release_exec(&exec);
+            return E_OUTOFMEMORY;
+        }
+
+        for(i=0; i < func->arg_cnt; i++) {
+            v = get_arg(dp, i);
+            if(V_VT(v) == (VT_VARIANT|VT_BYREF)) {
+                if(func->args[i].by_ref)
+                    exec.args[i] = *v;
+                else
+                    hres = VariantCopy(exec.args+i, V_VARIANTREF(v));
+            }else {
+                hres = VariantCopy(exec.args+i, v);
+            }
+            if(FAILED(hres)) {
+                release_exec(&exec);
+                return hres;
+            }
+        }
+    }else {
+        exec.args = NULL;
     }
 
     exec.stack_size = 16;
     exec.top = 0;
     exec.stack = heap_alloc(exec.stack_size * sizeof(VARIANT));
-    if(!exec.stack)
+    if(!exec.stack) {
+        release_exec(&exec);
         return E_OUTOFMEMORY;
+    }
 
-    exec.code = func->code_ctx;
     exec.instr = exec.code->instrs + func->code_off;
     exec.script = ctx;
     exec.func = func;
@@ -851,7 +907,7 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT
     }
 
     assert(!exec.top);
-    heap_free(exec.stack);
+    release_exec(&exec);
 
     return hres;
 }
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 0e6d57e..1362d9e 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -70,6 +70,11 @@ static inline unsigned arg_cnt(const DISPPARAMS *dp)
     return dp->cArgs - dp->cNamedArgs;
 }
 
+static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
+{
+    return dp->rgvarg + dp->cArgs-i-1;
+}
+
 typedef struct _dynamic_var_t {
     struct _dynamic_var_t *next;
     VARIANT v;



More information about the wine-tests-results mailing list