[PATCH v3 1/2] msscript: Cache state of IActiveScript in ScriptHost struct.

Jactry Zeng jzeng at codeweavers.com
Mon Sep 16 09:19:24 CDT 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/msscript.ocx/msscript.c       | 20 ++++++-
 dlls/msscript.ocx/tests/msscript.c | 91 +++++++++++++++++++++++++++++-
 2 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index 6e4c8d166a..49040b9455 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -71,6 +71,7 @@ typedef struct ScriptHost {
 
     IActiveScript *script;
     IActiveScriptParse *parse;
+    SCRIPTSTATE script_state;
     CLSID clsid;
 
     struct list named_items;
@@ -568,6 +569,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
         WARN("InitNew failed, %#x\n", hr);
         goto failed;
     }
+    host->script_state = SCRIPTSTATE_INITIALIZED;
 
     *ret = host;
     return S_OK;
@@ -952,6 +954,20 @@ static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name,
     return hr;
 }
 
+static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state, BOOL check_state)
+{
+    HRESULT hr;
+
+    if (check_state && (host->script_state == SCRIPTSTATE_STARTED))
+        return S_OK;
+
+    hr = IActiveScript_SetScriptState(host->script, state);
+    if (SUCCEEDED(hr))
+        host->script_state = state;
+
+    return hr;
+}
+
 static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
 {
     ScriptControl *This = impl_from_IScriptControl(iface);
@@ -962,7 +978,7 @@ static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
         return E_FAIL;
 
     clear_named_items(This->host);
-    return IActiveScript_SetScriptState(This->host->script, SCRIPTSTATE_INITIALIZED);
+    return set_script_state(This->host, SCRIPTSTATE_INITIALIZED, FALSE);
 }
 
 static HRESULT WINAPI ScriptControl_AddCode(IScriptControl *iface, BSTR code)
@@ -987,7 +1003,7 @@ static HRESULT WINAPI ScriptControl_Eval(IScriptControl *iface, BSTR expression,
     if (!This->host || This->state != Initialized)
         return E_FAIL;
 
-    hr = IActiveScript_SetScriptState(This->host->script, SCRIPTSTATE_STARTED);
+    hr = set_script_state(This->host, SCRIPTSTATE_STARTED, TRUE);
     if (FAILED(hr))
         return hr;
 
diff --git a/dlls/msscript.ocx/tests/msscript.c b/dlls/msscript.ocx/tests/msscript.c
index 2d500d8308..8ed4af2e6f 100644
--- a/dlls/msscript.ocx/tests/msscript.c
+++ b/dlls/msscript.ocx/tests/msscript.c
@@ -95,6 +95,8 @@ DEFINE_EXPECT(Close);
 DEFINE_EXPECT(SetScriptSite);
 DEFINE_EXPECT(QI_IActiveScriptParse);
 DEFINE_EXPECT(SetScriptState_INITIALIZED);
+DEFINE_EXPECT(SetScriptState_STARTED);
+DEFINE_EXPECT(ParseScriptText);
 DEFINE_EXPECT(AddNamedItem);
 
 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
@@ -147,8 +149,8 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    CHECK_EXPECT(ParseScriptText);
+    return S_OK;
 }
 
 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
@@ -304,6 +306,10 @@ static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTST
         CHECK_EXPECT(SetScriptState_INITIALIZED);
         return S_OK;
     }
+    else if (ss == SCRIPTSTATE_STARTED) {
+        CHECK_EXPECT(SetScriptState_STARTED);
+        return S_OK;
+    }
     else
         ok(0, "unexpected call, state %u\n", ss);
 
@@ -1381,7 +1387,7 @@ static void _check_error(IScriptControl *sc, LONG exp_num, int line)
     {
         error_num = 0xdeadbeef;
         hr = IScriptError_get_Number(script_err, &error_num);
-        ok_(__FILE__,line)(hr == S_OK, "IScriptError_get_Number failed: 0x%08x.", hr);
+        ok_(__FILE__,line)(hr == S_OK, "IScriptError_get_Number failed: 0x%08x.\n", hr);
         ok_(__FILE__,line)(error_num == exp_num, "got wrong error number: %d, expected %d.\n",
                            error_num, exp_num);
         IScriptError_Release(script_err);
@@ -1485,6 +1491,85 @@ static void test_IScriptControl_Eval(void)
     SysFreeString(script_str);
 
     IScriptControl_Release(sc);
+
+    /* custom script engine */
+    if (register_script_engine())
+    {
+        hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
+                              &IID_IScriptControl, (void **)&sc);
+        ok(hr == S_OK, "Failed to create IScriptControl interface: 0x%08x.\n", hr);
+
+        SET_EXPECT(CreateInstance);
+        SET_EXPECT(SetInterfaceSafetyOptions);
+        SET_EXPECT(SetScriptSite);
+        SET_EXPECT(QI_IActiveScriptParse);
+        SET_EXPECT(InitNew);
+
+        language= a2bstr("testscript");
+        hr = IScriptControl_put_Language(sc, language);
+        ok(hr == S_OK, "IScriptControl_put_Language failed: 0x%08x.\n", hr);
+        SysFreeString(language);
+
+        CHECK_CALLED(CreateInstance);
+        CHECK_CALLED(SetInterfaceSafetyOptions);
+        CHECK_CALLED(SetScriptSite);
+        CHECK_CALLED(QI_IActiveScriptParse);
+        CHECK_CALLED(InitNew);
+
+        SET_EXPECT(SetScriptState_STARTED);
+        SET_EXPECT(ParseScriptText);
+        script_str = a2bstr("var1 = 1 + 1");
+        V_VT(&var) = VT_NULL;
+        V_I4(&var) = 0xdeadbeef;
+        hr = IScriptControl_Eval(sc, script_str, &var);
+        ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr);
+        ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n",
+           V_VT(&var), V_I4(&var));
+        SysFreeString(script_str);
+        CHECK_CALLED(SetScriptState_STARTED);
+        CHECK_CALLED(ParseScriptText);
+
+        SET_EXPECT(ParseScriptText);
+        script_str = a2bstr("var2 = 10 + var1");
+        V_VT(&var) = VT_NULL;
+        V_I4(&var) = 0xdeadbeef;
+        hr = IScriptControl_Eval(sc, script_str, &var);
+        ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr);
+        ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n",
+           V_VT(&var), V_I4(&var));
+        SysFreeString(script_str);
+        CHECK_CALLED(ParseScriptText);
+
+        SET_EXPECT(SetScriptState_INITIALIZED);
+        hr = IScriptControl_Reset(sc);
+        ok(hr == S_OK, "IScriptControl_Reset failed: 0x%08x.\n", hr);
+        CHECK_CALLED(SetScriptState_INITIALIZED);
+
+        SET_EXPECT(SetScriptState_STARTED);
+        SET_EXPECT(ParseScriptText);
+        script_str = a2bstr("var2 = 10 + var1");
+        V_VT(&var) = VT_NULL;
+        V_I4(&var) = 0xdeadbeef;
+        hr = IScriptControl_Eval(sc, script_str, &var);
+        ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr);
+        ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n",
+           V_VT(&var), V_I4(&var));
+        SysFreeString(script_str);
+        CHECK_CALLED(SetScriptState_STARTED);
+        CHECK_CALLED(ParseScriptText);
+
+        IActiveScriptSite_Release(site);
+
+        init_registry(FALSE);
+
+        SET_EXPECT(Close);
+
+        IScriptControl_Release(sc);
+
+        CHECK_CALLED(Close);
+    }
+    else
+        skip("Could not register TestScript engine.\n");
 }
 
 START_TEST(msscript)
-- 
2.23.0





More information about the wine-devel mailing list