Jacek Caban : vbscript: Added interpreter support for sub arguments.

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


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 14 12:56:45 2011 +0200

vbscript: Added interpreter support for sub arguments.

---

 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 b697988..9dbce68 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;
 
@@ -814,9 +825,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;
 
@@ -825,18 +849,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;
@@ -854,7 +910,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-cvs mailing list