Fwd: 79194: [PATCH 10/13] vbscript: Added CreateObject implementation

Dan Kegel dank at kegel.com
Thu Sep 22 11:47:41 CDT 2011


Didn't build here, did you forget to add dependency on ole32?

ccache gcc -c -I. -I. -I../../include -I../../include  -D__WINESRC__
-D_REENTRANT -fPIC -Wall -pipe -fno-strict-aliasing
-Wdeclaration-after-statement -Wempty-body -Wstrict-prototypes
-Wtype-limits -Wwrite-strings -Wpointer-arith -Wlogical-op  -g -O0
-Werror -Wno-unused-but-set-variable -Wno-unused-but-set-parameter  -o
vwin32.o vwin32.c
global.o: In function `create_object':
/home/bob/wineslave.dir/sandbox/slave/runtests-default/build/dlls/vbscript/global.c:74:
undefined reference to `CLSIDFromProgID'
/home/bob/wineslave.dir/sandbox/slave/runtests-default/build/dlls/vbscript/global.c:92:
undefined reference to `CoGetClassObject'
/home/bob/wineslave.dir/sandbox/slave/runtests-default/build/dlls/vbscript/global.c:114:
undefined reference to `CoTaskMemFree'
collect2: ld returned 1 exit status
winegcc: ccache failed
make[1]: *** [vbscript.dll.so] Error 2


---------- Forwarded message ----------
From:  <buildbot at kegel.com>
Date: Thu, Sep 22, 2011 at 8:01 AM
Subject: Re: 79194: [PATCH 10/13] vbscript: Added CreateObject implementation
To: dank at kegel.com


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-default
while building Wine.
Full details are available at:
http://buildbot.kegel.com/builders/runtests-default/builds/26 (though
maybe not for long, as I'm still reinstalling the buildbot
periodically while experimenting)
BUILD FAILED: failed shell_2

Errors:
make: *** [dlls/vbscript] Error 2
-------------- next part --------------
From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 01/13] vbscript: Added for..to statement parser implementation
Message-Id: <4E7B2890.4010807 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:22:40 +0200

---
  dlls/vbscript/lex.c    |    6 ++++++
  dlls/vbscript/parse.h  |   10 ++++++++++
  dlls/vbscript/parser.y |   28 ++++++++++++++++++++++++++--
  3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index f42d2fd..ac3d65e 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -44,6 +44,7 @@ static const WCHAR errorW[] = {'e','r','r','o','r',0};
 static const WCHAR exitW[] = {'e','x','i','t',0};
 static const WCHAR explicitW[] = {'e','x','p','l','i','c','i','t',0};
 static const WCHAR falseW[] = {'f','a','l','s','e',0};
+static const WCHAR forW[] = {'f','o','r',0};
 static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
 static const WCHAR getW[] = {'g','e','t',0};
 static const WCHAR gotoW[] = {'g','o','t','o',0};
@@ -68,9 +69,11 @@ static const WCHAR publicW[] = {'p','u','b','l','i','c',0};
 static const WCHAR remW[] = {'r','e','m',0};
 static const WCHAR resumeW[] = {'r','e','s','u','m','e',0};
 static const WCHAR setW[] = {'s','e','t',0};
+static const WCHAR stepW[] = {'s','t','e','p',0};
 static const WCHAR stopW[] = {'s','t','o','p',0};
 static const WCHAR subW[] = {'s','u','b',0};
 static const WCHAR thenW[] = {'t','h','e','n',0};
+static const WCHAR toW[] = {'t','o',0};
 static const WCHAR trueW[] = {'t','r','u','e',0};
 static const WCHAR untilW[] = {'u','n','t','i','l',0};
 static const WCHAR wendW[] = {'w','e','n','d',0};
@@ -99,6 +102,7 @@ static const struct {
     {exitW,      tEXIT},
     {explicitW,  tEXPLICIT},
     {falseW,     tFALSE},
+    {forW,       tFOR},
     {functionW,  tFUNCTION},
     {getW,       tGET},
     {gotoW,      tGOTO},
@@ -123,9 +127,11 @@ static const struct {
     {remW,       tREM},
     {resumeW,    tRESUME},
     {setW,       tSET},
+    {stepW,      tSTEP},
     {stopW,      tSTOP},
     {subW,       tSUB},
     {thenW,      tTHEN},
+    {toW,        tTO},
     {trueW,      tTRUE},
     {untilW,     tUNTIL},
     {wendW,      tWEND},
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 8e4be57..a5bd505 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -106,6 +106,7 @@ typedef enum {
     STAT_EXITFUNC,
     STAT_EXITPROP,
     STAT_EXITSUB,
+    STAT_FORTO,
     STAT_FUNC,
     STAT_IF,
     STAT_ONERROR,
@@ -198,6 +199,15 @@ typedef struct {
 
 typedef struct {
     statement_t stat;
+    const WCHAR *identifier;
+    expression_t *from_expr;
+    expression_t *to_expr;
+    expression_t *step_expr;
+    statement_t *body;
+} forto_statement_t;
+
+typedef struct {
+    statement_t stat;
     BOOL resume_next;
 } onerror_statement_t;
 
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 8435e92..3b30051 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -52,6 +52,7 @@ static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expr
 static statement_t *new_set_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_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*);
+static statement_t *new_forto_statement(parser_ctx_t*,const WCHAR*,expression_t*,expression_t*,expression_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 statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
@@ -102,7 +103,7 @@ static statement_t *link_statements(statement_t*,statement_t*);
 %token tIS tLTEQ tGTEQ tMOD
 %token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST
 %token tIF tELSE tELSEIF tEND tTHEN tEXIT
-%token tWHILE tWEND tDO tLOOP tUNTIL
+%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP
 %token tBYREF tBYVAL
 %token tOPTION tEXPLICIT
 %token tSTOP
@@ -118,7 +119,7 @@ static statement_t *link_statements(statement_t*,statement_t*);
 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
 %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
 %type <member> MemberExpression
-%type <expression> Arguments_opt ArgumentList_opt ArgumentList
+%type <expression> Arguments_opt ArgumentList_opt ArgumentList Step_opt
 %type <bool> OptionExplicit_opt DoType
 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
 %type <func_decl> FunctionDecl PropertyDecl
@@ -186,6 +187,8 @@ SimpleStatement
     | tON tERROR tRESUME tNEXT              { $$ = new_onerror_statement(ctx, TRUE); CHECK_ERROR; }
     | tON tERROR tGOTO '0'                  { $$ = new_onerror_statement(ctx, FALSE); CHECK_ERROR; }
     | tCONST ConstDeclList                  { $$ = new_const_statement(ctx, $2); CHECK_ERROR; }
+    | tFOR tIdentifier '=' Expression tTO Expression Step_opt tNL StatementsNl_opt tNEXT
+                                            { $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
 
 MemberExpression
     : tIdentifier                           { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
@@ -206,6 +209,10 @@ DoType
     : tWHILE        { $$ = TRUE; }
     | tUNTIL        { $$ = FALSE; }
 
+Step_opt
+    : /* empty */                           { $$ = NULL;}
+    | tSTEP Expression                      { $$ = $2; }
+
 IfStatement
     : tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF
                                             { $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
@@ -626,6 +633,23 @@ static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type
     return &stat->stat;
 }
 
+static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *from_expr,
+        expression_t *to_expr, expression_t *step_expr, statement_t *body)
+{
+    forto_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_FORTO, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->identifier = identifier;
+    stat->from_expr = from_expr;
+    stat->to_expr = to_expr;
+    stat->step_expr = step_expr;
+    stat->body = body;
+    return &stat->stat;
+}
+
 static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
         statement_t *else_stat)
 {

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 02/13] vbscript: Added for..to statement compiler implementation
Message-Id: <4E7B28AE.2010305 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:23:10 +0200

---
  dlls/vbscript/compile.c  |   77 
++++++++++++++++++++++++++++++++++++++++++++++
  dlls/vbscript/interp.c   |   30 ++++++++++++++++++
  dlls/vbscript/vbscript.h |    4 ++
  3 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 9cfe45b..1f1f041 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -169,6 +169,18 @@ static HRESULT push_instr_int(compile_ctx_t *ctx, vbsop_t op, LONG arg)
     return S_OK;
 }
 
+static HRESULT push_instr_uint(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
+{
+    unsigned ret;
+
+    ret = push_instr(ctx, op);
+    if(ret == -1)
+        return E_OUTOFMEMORY;
+
+    instr_ptr(ctx, ret)->arg1.uint = arg;
+    return S_OK;
+}
+
 static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
 {
     unsigned ret;
@@ -603,6 +615,68 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
     return S_OK;
 }
 
+static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
+{
+    unsigned step_instr, instr;
+    BSTR identifier;
+    HRESULT hres;
+
+    identifier = alloc_bstr_arg(ctx, stat->identifier);
+    if(!identifier)
+        return E_OUTOFMEMORY;
+
+    hres = compile_expression(ctx, stat->from_expr);
+    if(FAILED(hres))
+        return hres;
+
+    instr = push_instr(ctx, OP_assign_ident);
+    if(instr == -1)
+        return E_OUTOFMEMORY;
+    instr_ptr(ctx, instr)->arg1.bstr = identifier;
+
+    hres = compile_expression(ctx, stat->to_expr);
+    if(FAILED(hres))
+        return hres;
+
+    if(push_instr(ctx, OP_val) == -1)
+        return E_OUTOFMEMORY;
+
+    if(stat->step_expr) {
+        hres = compile_expression(ctx, stat->step_expr);
+        if(FAILED(hres))
+            return hres;
+
+        if(push_instr(ctx, OP_val) == -1)
+            return E_OUTOFMEMORY;
+    }else {
+        hres = push_instr_int(ctx, OP_short, 1);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    step_instr = push_instr(ctx, OP_step);
+    if(step_instr == -1)
+        return E_OUTOFMEMORY;
+    instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
+
+    hres = compile_statement(ctx, stat->body);
+    if(FAILED(hres))
+        return hres;
+
+    instr = push_instr(ctx, OP_incc);
+    if(instr == -1)
+        return E_OUTOFMEMORY;
+    instr_ptr(ctx, instr)->arg1.bstr = identifier;
+
+    hres = push_instr_addr(ctx, OP_jmp, step_instr);
+    if(FAILED(hres))
+        return hres;
+
+    instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
+
+    return push_instr_uint(ctx, OP_pop, 2);
+}
+
 static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
 {
     HRESULT hres;
@@ -799,6 +873,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
         case STAT_EXITSUB:
             hres = compile_exitsub_statement(ctx);
             break;
+        case STAT_FORTO:
+            hres = compile_forto_statement(ctx, (forto_statement_t*)stat);
+            break;
         case STAT_FUNC:
             hres = compile_function_statement(ctx, (function_statement_t*)stat);
             break;
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index c2ffd98..1327c17 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -682,6 +682,22 @@ static HRESULT interp_const(exec_ctx_t *ctx)
     return add_dynamic_var(ctx, arg, TRUE, val.v, val.owned);
 }
 
+static HRESULT interp_val(exec_ctx_t *ctx)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT interp_pop(exec_ctx_t *ctx)
+{
+    const unsigned n = ctx->instr->arg1.uint;
+
+    TRACE("%u\n", n);
+
+    stack_popn(ctx, n);
+    return S_OK;
+}
+
 static HRESULT interp_new(exec_ctx_t *ctx)
 {
     const WCHAR *arg = ctx->instr->arg1.bstr;
@@ -710,6 +726,13 @@ static HRESULT interp_new(exec_ctx_t *ctx)
     return stack_push(ctx, &v);
 }
 
+static HRESULT interp_step(exec_ctx_t *ctx)
+{
+    const BSTR ident = ctx->instr->arg2.bstr;
+    FIXME("%s\n", debugstr_w(ident));
+    return E_NOTIMPL;
+}
+
 static HRESULT interp_jmp(exec_ctx_t *ctx)
 {
     const unsigned arg = ctx->instr->arg1.uint;
@@ -1439,6 +1462,13 @@ static HRESULT interp_neg(exec_ctx_t *ctx)
     return stack_push(ctx, &v);
 }
 
+static HRESULT interp_incc(exec_ctx_t *ctx)
+{
+    const BSTR ident = ctx->instr->arg1.bstr;
+    FIXME("%s\n", debugstr_w(ident));
+    return E_NOTIMPL;
+}
+
 static const instr_func_t op_funcs[] = {
 #define X(x,n,a,b) interp_ ## x,
 OP_LIST
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index bd55719..4b0a569 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -199,6 +199,7 @@ typedef enum {
     X(icallv,         1, ARG_BSTR,    ARG_UINT)   \
     X(idiv,           1, 0,           0)          \
     X(imp,            1, 0,           0)          \
+    X(incc,           1, ARG_BSTR,    0)          \
     X(is,             1, 0,           0)          \
     X(jmp,            0, ARG_ADDR,    0)          \
     X(jmp_false,      0, ARG_ADDR,    0)          \
@@ -218,13 +219,16 @@ typedef enum {
     X(nothing,        1, 0,           0)          \
     X(null,           1, 0,           0)          \
     X(or,             1, 0,           0)          \
+    X(pop,            1, ARG_UINT,    0)          \
     X(ret,            0, 0,           0)          \
     X(set_ident,      1, ARG_BSTR,    0)          \
     X(set_member,     1, ARG_BSTR,    0)          \
     X(short,          1, ARG_INT,     0)          \
+    X(step,           0, ARG_ADDR,    ARG_BSTR)   \
     X(stop,           1, 0,           0)          \
     X(string,         1, ARG_STR,     0)          \
     X(sub,            1, 0,           0)          \
+    X(val,            1, 0,           0)          \
     X(xor,            1, 0,           0)
 
 typedef enum {

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 03/13] vbscript: Added interp_val implementation
Message-Id: <4E7B28BD.3090801 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:23:25 +0200

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

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 1327c17..5e41845 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -684,8 +684,24 @@ static HRESULT interp_const(exec_ctx_t *ctx)
 
 static HRESULT interp_val(exec_ctx_t *ctx)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    variant_val_t val;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = stack_pop_val(ctx, &val);
+    if(FAILED(hres))
+        return hres;
+
+    if(!val.owned) {
+        V_VT(&v) = VT_EMPTY;
+        hres = VariantCopy(&v, val.v);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    return stack_push(ctx, val.owned ? val.v : &v);
 }
 
 static HRESULT interp_pop(exec_ctx_t *ctx)

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 04/13] vbscript: Added interp_step implementation
Message-Id: <4E7B28D7.3090304 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:23:51 +0200

---
  dlls/vbscript/interp.c |   41 +++++++++++++++++++++++++++++++++++++++--
  1 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 5e41845..c95183d 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -245,6 +245,12 @@ static inline VARIANT *stack_pop(exec_ctx_t *ctx)
     return ctx->stack + --ctx->top;
 }
 
+static inline VARIANT *stack_top(exec_ctx_t *ctx, unsigned n)
+{
+    assert(ctx->top >= n);
+    return ctx->stack + (ctx->top-n-1);
+}
+
 static HRESULT stack_push(exec_ctx_t *ctx, VARIANT *v)
 {
     if(ctx->stack_size == ctx->top) {
@@ -745,8 +751,39 @@ static HRESULT interp_new(exec_ctx_t *ctx)
 static HRESULT interp_step(exec_ctx_t *ctx)
 {
     const BSTR ident = ctx->instr->arg2.bstr;
-    FIXME("%s\n", debugstr_w(ident));
-    return E_NOTIMPL;
+    BOOL gteq_zero;
+    VARIANT zero;
+    ref_t ref;
+    HRESULT hres;
+
+    TRACE("%s\n", debugstr_w(ident));
+
+    V_VT(&zero) = VT_I2;
+    V_I2(&zero) = 0;
+    hres = VarCmp(stack_top(ctx, 0), &zero, ctx->script->lcid, 0);
+    if(FAILED(hres))
+        return hres;
+
+    gteq_zero = hres == VARCMP_GT || hres == VARCMP_EQ;
+
+    hres = lookup_identifier(ctx, ident, VBDISP_ANY, &ref);
+    if(FAILED(hres))
+        return hres;
+
+    if(ref.type != REF_VAR) {
+        FIXME("%s is not REF_VAR\n", debugstr_w(ident));
+        return E_FAIL;
+    }
+
+    hres = VarCmp(ref.u.v, stack_top(ctx, 1), ctx->script->lcid, 0);
+    if(FAILED(hres))
+        return hres;
+
+    if(hres == VARCMP_EQ || hres == (gteq_zero ? VARCMP_LT : VARCMP_GT))
+        ctx->instr++;
+    else
+        instr_jmp(ctx, ctx->instr->arg1.uint);
+    return S_OK;
 }
 
 static HRESULT interp_jmp(exec_ctx_t *ctx)

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 05/13] vbscript: Added interp_incc implementation
Message-Id: <4E7B28E5.8090408 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:24:05 +0200

---
  dlls/vbscript/interp.c |   24 ++++++++++++++++++++++--
  1 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index c95183d..08ea83e 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -1518,8 +1518,28 @@ static HRESULT interp_neg(exec_ctx_t *ctx)
 static HRESULT interp_incc(exec_ctx_t *ctx)
 {
     const BSTR ident = ctx->instr->arg1.bstr;
-    FIXME("%s\n", debugstr_w(ident));
-    return E_NOTIMPL;
+    VARIANT v;
+    ref_t ref;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = lookup_identifier(ctx, ident, VBDISP_LET, &ref);
+    if(FAILED(hres))
+        return hres;
+
+    if(ref.type != REF_VAR) {
+        FIXME("ref.type is not REF_VAR\n");
+        return E_FAIL;
+    }
+
+    hres = VarAdd(stack_top(ctx, 0), ref.u.v, &v);
+    if(FAILED(hres))
+        return hres;
+
+    VariantClear(ref.u.v);
+    *ref.u.v = v;
+    return S_OK;
 }
 
 static const instr_func_t op_funcs[] = {

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 06/13] vbscript: Added for..in statement tests
Message-Id: <4E7B28F4.3090502 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:24:20 +0200

---
  dlls/vbscript/tests/lang.vbs |   56 
+++++++++++++++++++++++++++++++++++++++++-
  1 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 2d712f5..3b3ad50 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -18,7 +18,7 @@
 
 Option Explicit
 
-dim x, y
+dim x, y, z
 
 call ok(true, "true is not true?")
 ok true, "true is not true?"
@@ -333,6 +333,60 @@ do
     ok false, "exit do didn't work"
 loop while true
 
+y = "for1:"
+for x = 5 to 8
+    y = y & " " & x
+next
+Call ok(y = "for1: 5 6 7 8", "y = " & y)
+
+y = "for2:"
+for x = 5 to 8 step 2
+    y = y & " " & x
+next
+Call ok(y = "for2: 5 7", "y = " & y)
+
+y = "for3:"
+x = 2
+for x = x+3 to 8
+    y = y & " " & x
+next
+Call ok(y = "for3: 5 6 7 8", "y = " & y)
+
+y = "for4:"
+for x = 5 to 4
+    y = y & " " & x
+next
+Call ok(y = "for4:", "y = " & y)
+
+y = "for5:"
+for x = 5 to 3 step true
+    y = y & " " & x
+next
+Call ok(y = "for5: 5 4 3", "y = " & y)
+
+y = "for6:"
+z = 4
+for x = 5 to z step 3-4
+    y = y & " " & x
+    z = 0
+next
+Call ok(y = "for6: 5 4", "y = " & y)
+
+y = "for7:"
+z = 1
+for x = 5 to 8 step z
+    y = y & " " & x
+    z = 2
+next
+Call ok(y = "for7: 5 6 7 8", "y = " & y)
+
+y = "for8:"
+for x = 5 to 8
+    y = y & " " & x
+    x = x+1
+next
+Call ok(y = "for8: 5 7", "y = " & y)
+
 if false then
 Sub testsub
     x = true

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 07/13] vbscript: Added exit for statement support
Message-Id: <4E7B290C.6000604 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:24:44 +0200

---
  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

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 08/13] vbscript: Added support for DISPATCH_METHOD flags in invoke_builtin
Message-Id: <4E7B2922.9070308 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:25:06 +0200

---
  dlls/vbscript/vbdisp.c |   18 +++++++++++++-----
  1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 96df71a..d083d74 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -139,14 +139,15 @@ static HRESULT invoke_builtin(vbdisp_t *This, const builtin_prop_t *prop, WORD f
             FIXME("property does not support DISPATCH_PROPERTYGET\n");
             return E_FAIL;
         }
-        /* FALLTHROUGH */
+        break;
     case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
-        if(arg_cnt(dp) < prop->min_args || arg_cnt(dp) > (prop->max_args ? prop->max_args : prop->min_args)) {
-            FIXME("invalid number of arguments\n");
+        break;
+    case DISPATCH_METHOD:
+        if(prop->flags & (BP_GET|BP_GETPUT)) {
+            FIXME("Call on property\n");
             return E_FAIL;
         }
-
-        return prop->proc(This, dp->rgvarg, dp->cArgs, res);
+        break;
     case DISPATCH_PROPERTYPUT:
         if(!(prop->flags & (BP_GET|BP_GETPUT))) {
             FIXME("property does not support DISPATCH_PROPERTYPUT\n");
@@ -159,6 +160,13 @@ static HRESULT invoke_builtin(vbdisp_t *This, const builtin_prop_t *prop, WORD f
         FIXME("unsupported flags %x\n", flags);
         return E_NOTIMPL;
     }
+
+    if(arg_cnt(dp) < prop->min_args || arg_cnt(dp) > (prop->max_args ? prop->max_args : prop->min_args)) {
+        FIXME("invalid number of arguments\n");
+        return E_FAIL;
+    }
+
+    return prop->proc(This, dp->rgvarg, dp->cArgs, res);
 }
 
 static BOOL run_terminator(vbdisp_t *This)

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 09/13] vbscript: Lookup global object before host-provided objects
Message-Id: <4E7B292B.6090203 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:25:15 +0200

---
  dlls/vbscript/interp.c |   44 +++++++++++++++++++++++---------------------
  1 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 08ea83e..678b51a 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -126,12 +126,14 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
     if(lookup_dynamic_vars(ctx->func->type == FUNC_GLOBAL ? ctx->script->global_vars : ctx->dynamic_vars, name, ref))
         return S_OK;
 
-    hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
-    if(SUCCEEDED(hres)) {
-        ref->type = REF_DISP;
-        ref->u.d.disp = ctx->this_obj;
-        ref->u.d.id = id;
-        return S_OK;
+    if(ctx->func->type != FUNC_GLOBAL) {
+        hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
+        if(SUCCEEDED(hres)) {
+            ref->type = REF_DISP;
+            ref->u.d.disp = ctx->this_obj;
+            ref->u.d.id = id;
+            return S_OK;
+        }
     }
 
     if(ctx->func->type != FUNC_GLOBAL && lookup_dynamic_vars(ctx->script->global_vars, name, ref))
@@ -145,8 +147,22 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         }
     }
 
+    if(!strcmpiW(name, errW)) {
+        ref->type = REF_OBJ;
+        ref->u.obj = (IDispatch*)&ctx->script->err_obj->IDispatchEx_iface;
+        return S_OK;
+    }
+
+    hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, &id);
+    if(SUCCEEDED(hres)) {
+        ref->type = REF_DISP;
+        ref->u.d.disp = (IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
+        ref->u.d.id = id;
+        return S_OK;
+    }
+
     LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) {
-        if((item->flags & SCRIPTITEM_GLOBALMEMBERS) && item->disp != ctx->this_obj) {
+        if((item->flags & SCRIPTITEM_GLOBALMEMBERS)) {
             hres = disp_get_id(item->disp, name, invoke_type, FALSE, &id);
             if(SUCCEEDED(hres)) {
                 ref->type = REF_DISP;
@@ -180,20 +196,6 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
         }
     }
 
-    if(!strcmpiW(name, errW)) {
-        ref->type = REF_OBJ;
-        ref->u.obj = (IDispatch*)&ctx->script->err_obj->IDispatchEx_iface;
-        return S_OK;
-    }
-
-    hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, &id);
-    if(SUCCEEDED(hres)) {
-        ref->type = REF_DISP;
-        ref->u.d.disp = (IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
-        ref->u.d.id = id;
-        return S_OK;
-    }
-
     ref->type = REF_NONE;
     return S_OK;
 }

From: Jacek Caban <jacek at codeweavers.com>
Subject: [PATCH 10/13] vbscript: Added CreateObject implementation
Message-Id: <4E7B2937.4020100 at codeweavers.com>
Date: Thu, 22 Sep 2011 14:25:27 +0200

---
  dlls/vbscript/global.c        |  134 
++++++++++++++++++++++++++++++++++++++++-
  dlls/vbscript/vbscript.c      |    3 +
  dlls/vbscript/vbscript.h      |    3 +
  dlls/vbscript/vbscript_main.c |    1 +
  4 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c
index 3d58ea7..5af7e16 100644
--- a/dlls/vbscript/global.c
+++ b/dlls/vbscript/global.c
@@ -19,10 +19,118 @@
 #include "vbscript.h"
 #include "vbscript_defs.h"
 
+#include "mshtmhst.h"
+#include "objsafe.h"
+
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
 
+#define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
+
+/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
+const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
+    {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
+
+static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx)
+{
+    IInternetHostSecurityManager *secmgr;
+    IServiceProvider *sp;
+    HRESULT hres;
+
+    if(!ctx->site)
+        return NULL;
+
+    if(ctx->secmgr)
+        return ctx->secmgr;
+
+    hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
+    if(FAILED(hres))
+        return NULL;
+
+    hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager,
+            (void**)&secmgr);
+    IServiceProvider_Release(sp);
+    if(FAILED(hres))
+        return NULL;
+
+    return ctx->secmgr = secmgr;
+}
+
+static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid)
+{
+    IInternetHostSecurityManager *secmgr = NULL;
+    IObjectWithSite *obj_site;
+    struct CONFIRMSAFETY cs;
+    IClassFactoryEx *cfex;
+    IClassFactory *cf;
+    DWORD policy_size;
+    BYTE *bpolicy;
+    IUnknown *obj;
+    DWORD policy;
+    GUID guid;
+    HRESULT hres;
+
+    hres = CLSIDFromProgID(progid, &guid);
+    if(FAILED(hres))
+        return NULL;
+
+    TRACE("GUID %s\n", debugstr_guid(&guid));
+
+    if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
+        secmgr = get_sec_mgr(ctx);
+        if(!secmgr)
+            return NULL;
+
+        policy = 0;
+        hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN,
+                (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0);
+        if(FAILED(hres) || policy != URLPOLICY_ALLOW)
+            return NULL;
+    }
+
+    hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
+    if(FAILED(hres))
+        return NULL;
+
+    hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
+    if(SUCCEEDED(hres)) {
+        FIXME("Use IClassFactoryEx\n");
+        IClassFactoryEx_Release(cfex);
+    }
+
+    hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
+    if(FAILED(hres))
+        return NULL;
+
+    if(secmgr) {
+        cs.clsid = guid;
+        cs.pUnk = obj;
+        cs.dwFlags = 0;
+        hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
+                &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
+        if(SUCCEEDED(hres)) {
+            policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW;
+            CoTaskMemFree(bpolicy);
+        }
+
+        if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
+            IUnknown_Release(obj);
+            return NULL;
+        }
+    }
+
+    hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
+    if(SUCCEEDED(hres)) {
+        FIXME("ObjectWithSite\n");
+        IObjectWithSite_Release(obj_site);
+        IUnknown_Release(obj);
+        return NULL;
+    }
+
+    return obj;
+}
+
 static HRESULT Global_CCur(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
 {
     FIXME("\n");
@@ -483,8 +591,30 @@ static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VA
 
 static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    IUnknown *obj;
+    HRESULT hres;
+
+    TRACE("(%s)\n", debugstr_variant(arg));
+
+    if(V_VT(arg) != VT_BSTR) {
+        FIXME("non-bstr arg\n");
+        return E_INVALIDARG;
+    }
+
+    obj = create_object(This->desc->ctx, V_BSTR(arg));
+    if(!obj)
+        return VB_E_CANNOT_CREATE_OBJ;
+
+    if(res) {
+        hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&V_DISPATCH(res));
+        if(FAILED(hres))
+            return hres;
+
+        V_VT(res) = VT_DISPATCH;
+    }
+
+    IUnknown_Release(obj);
+    return S_OK;
 }
 
 static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 3ac9560..d4e8cca 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -129,6 +129,8 @@ static void destroy_script(script_ctx_t *ctx)
 
     if(ctx->host_global)
         IDispatch_Release(ctx->host_global);
+    if(ctx->secmgr)
+        IInternetHostSecurityManager_Release(ctx->secmgr);
     if(ctx->site)
         IActiveScriptSite_Release(ctx->site);
     if(ctx->err_obj)
@@ -516,6 +518,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
     if(!ctx)
         return E_OUTOFMEMORY;
 
+    ctx->safeopt = This->safeopt;
     vbsheap_init(&ctx->heap);
     list_init(&ctx->objects);
     list_init(&ctx->code_list);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 4b0a569..d8134fa 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -143,6 +143,9 @@ struct _script_ctx_t {
     IActiveScriptSite *site;
     LCID lcid;
 
+    IInternetHostSecurityManager *secmgr;
+    DWORD safeopt;
+
     IDispatch *host_global;
 
     class_desc_t script_desc;
diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c
index 4054d35..c47227f 100644
--- a/dlls/vbscript/vbscript_main.c
+++ b/dlls/vbscript/vbscript_main.c
@@ -20,6 +20,7 @@
 
 #include "vbscript.h"
 #include "objsafe.h"
+#include "mshtmhst.h"
 #include "rpcproxy.h"
 #include "vbscript_classes.h"
 #include "vbsglobal.h"


More information about the wine-devel mailing list