Jacek Caban : jscript: Added support for host objects being part of scope chain.

Alexandre Julliard julliard at winehq.org
Thu Sep 13 14:39:22 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 13 14:34:25 2012 +0200

jscript: Added support for host objects being part of scope chain.

---

 dlls/jscript/engine.c    |   28 ++++++++++++----------------
 dlls/jscript/engine.h    |    5 +++--
 dlls/jscript/function.c  |    2 +-
 dlls/jscript/tests/run.c |   32 ++++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index eb2adca..f7c7d1a 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -268,7 +268,7 @@ static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
         IDispatch_AddRef(disp);
 }
 
-HRESULT scope_push(scope_chain_t *scope, jsdisp_t *obj, scope_chain_t **ret)
+HRESULT scope_push(scope_chain_t *scope, jsdisp_t *jsobj, IDispatch *obj, scope_chain_t **ret)
 {
     scope_chain_t *new_scope;
 
@@ -278,7 +278,8 @@ HRESULT scope_push(scope_chain_t *scope, jsdisp_t *obj, scope_chain_t **ret)
 
     new_scope->ref = 1;
 
-    jsdisp_addref(obj);
+    IDispatch_AddRef(obj);
+    new_scope->jsobj = jsobj;
     new_scope->obj = obj;
 
     if(scope) {
@@ -309,7 +310,7 @@ void scope_release(scope_chain_t *scope)
     if(scope->next)
         scope_release(scope->next);
 
-    jsdisp_release(scope->obj);
+    IDispatch_Release(scope->obj);
     heap_free(scope);
 }
 
@@ -511,9 +512,12 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
     TRACE("%s\n", debugstr_w(identifier));
 
     for(scope = ctx->exec_ctx->scope_chain; scope; scope = scope->next) {
-        hres = jsdisp_get_id(scope->obj, identifier, 0, &id);
+        if(scope->jsobj)
+            hres = jsdisp_get_id(scope->jsobj, identifier, fdexNameImplicit, &id);
+        else
+            hres = disp_get_id(ctx, scope->obj, identifier, fdexNameImplicit, &id);
         if(SUCCEEDED(hres)) {
-            exprval_set_idref(ret, to_disp(scope->obj), id);
+            exprval_set_idref(ret, scope->obj, id);
             return S_OK;
         }
     }
@@ -668,7 +672,6 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
 static HRESULT interp_push_scope(exec_ctx_t *ctx)
 {
     IDispatch *disp;
-    jsdisp_t *obj;
     VARIANT *v;
     HRESULT hres;
 
@@ -680,15 +683,8 @@ static HRESULT interp_push_scope(exec_ctx_t *ctx)
     if(FAILED(hres))
         return hres;
 
-    obj = to_jsdisp(disp);
-    if(!obj) {
-        IDispatch_Release(disp);
-        FIXME("disp is not jsdisp\n");
-        return E_NOTIMPL;
-    }
-
-    hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain);
-    jsdisp_release(obj);
+    hres = scope_push(ctx->scope_chain, to_jsdisp(disp), disp, &ctx->scope_chain);
+    IDispatch_Release(disp);
     return hres;
 }
 
@@ -2509,7 +2505,7 @@ static HRESULT unwind_exception(exec_ctx_t *ctx)
         if(FAILED(hres))
             return hres;
 
-        hres = scope_push(ctx->scope_chain, scope_obj, &ctx->scope_chain);
+        hres = scope_push(ctx->scope_chain, scope_obj, to_disp(scope_obj), &ctx->scope_chain);
         jsdisp_release(scope_obj);
     }else {
         VARIANT v;
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index b3648af..22283aa 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -203,11 +203,12 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
 
 typedef struct _scope_chain_t {
     LONG ref;
-    jsdisp_t *obj;
+    jsdisp_t *jsobj;
+    IDispatch *obj;
     struct _scope_chain_t *next;
 } scope_chain_t;
 
-HRESULT scope_push(scope_chain_t*,jsdisp_t*,scope_chain_t**) DECLSPEC_HIDDEN;
+HRESULT scope_push(scope_chain_t*,jsdisp_t*,IDispatch*,scope_chain_t**) DECLSPEC_HIDDEN;
 void scope_release(scope_chain_t*) DECLSPEC_HIDDEN;
 
 static inline void scope_addref(scope_chain_t *scope)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 23ce98c..e7a011d 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -182,7 +182,7 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
         return hres;
     }
 
-    hres = scope_push(function->scope_chain, var_disp, &scope);
+    hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
     if(SUCCEEDED(hres)) {
         hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx);
         scope_release(scope);
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index 4a9f36d..30a1f9c 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -88,6 +88,8 @@ DEFINE_EXPECT(puredisp_noprop_d);
 DEFINE_EXPECT(testobj_delete);
 DEFINE_EXPECT(testobj_value);
 DEFINE_EXPECT(testobj_prop_d);
+DEFINE_EXPECT(testobj_withprop_d);
+DEFINE_EXPECT(testobj_withprop_i);
 DEFINE_EXPECT(testobj_noprop_d);
 DEFINE_EXPECT(testobj_onlydispid_d);
 DEFINE_EXPECT(testobj_onlydispid_i);
@@ -124,6 +126,7 @@ DEFINE_EXPECT(DeleteMemberByDispID);
 
 #define DISPID_TESTOBJ_PROP         0x2000
 #define DISPID_TESTOBJ_ONLYDISPID   0x2001
+#define DISPID_TESTOBJ_WITHPROP     0x2002
 
 #define JS_E_INVALID_CHAR 0x800a03f6
 
@@ -297,6 +300,12 @@ static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         *pid = DISPID_TESTOBJ_PROP;
         return S_OK;
     }
+    if(!strcmp_wa(bstrName, "withProp")) {
+        CHECK_EXPECT(testobj_withprop_d);
+        test_grfdex(grfdex, fdexNameCaseSensitive|fdexNameImplicit);
+        *pid = DISPID_TESTOBJ_WITHPROP;
+        return S_OK;
+    }
     if(!strcmp_wa(bstrName, "noprop")) {
         CHECK_EXPECT(testobj_noprop_d);
         test_grfdex(grfdex, fdexNameCaseSensitive);
@@ -360,6 +369,23 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
         ok(pei != NULL, "pei == NULL\n");
         return DISP_E_MEMBERNOTFOUND;
+     case DISPID_TESTOBJ_WITHPROP:
+        CHECK_EXPECT(testobj_withprop_i);
+
+        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        V_VT(pvarRes) = VT_I4;
+        V_I4(pvarRes) = 1;
+
+        return S_OK;
     }
 
     ok(0, "unexpected call %x\n", id);
@@ -1754,6 +1780,12 @@ static BOOL run_tests(void)
                    "});");
     CHECK_CALLED(global_testargtypes_i);
 
+    SET_EXPECT(testobj_withprop_d);
+    SET_EXPECT(testobj_withprop_i);
+    parse_script_a("var t = (function () { with(testObj) { return withProp; }})(); ok(t === 1, 't = ' + t);");
+    CHECK_CALLED(testobj_withprop_d);
+    CHECK_CALLED(testobj_withprop_i);
+
     run_from_res("lang.js");
     run_from_res("api.js");
     run_from_res("regexp.js");




More information about the wine-cvs mailing list