Jacek Caban : jscript: Add IActiveScriptError implementation.

Alexandre Julliard julliard at winehq.org
Thu Jan 30 16:10:24 CST 2020


Module: wine
Branch: master
Commit: 75482382979193af5321816f1e03a9f785cafca9
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=75482382979193af5321816f1e03a9f785cafca9

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Jan 30 15:50:47 2020 +0100

jscript: Add IActiveScriptError implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/jscript.c   | 133 +++++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/tests/run.c |  13 +++--
 2 files changed, 139 insertions(+), 7 deletions(-)

diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c
index 1564e859b8..81bf7e440d 100644
--- a/dlls/jscript/jscript.c
+++ b/dlls/jscript/jscript.c
@@ -64,6 +64,12 @@ typedef struct {
     struct list queued_code;
 } JScript;
 
+typedef struct {
+    IActiveScriptError IActiveScriptError_iface;
+    LONG ref;
+    jsexcept_t ei;
+} JScriptError;
+
 void script_release(script_ctx_t *ctx)
 {
     if(--ctx->ref)
@@ -101,6 +107,106 @@ static inline BOOL is_started(script_ctx_t *ctx)
         || ctx->state == SCRIPTSTATE_DISCONNECTED;
 }
 
+static inline JScriptError *impl_from_IActiveScriptError(IActiveScriptError *iface)
+{
+    return CONTAINING_RECORD(iface, JScriptError, IActiveScriptError_iface);
+}
+
+static HRESULT WINAPI JScriptError_QueryInterface(IActiveScriptError *iface, REFIID riid, void **ppv)
+{
+    JScriptError *This = impl_from_IActiveScriptError(iface);
+
+    if(IsEqualGUID(riid, &IID_IUnknown)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IActiveScriptError_iface;
+    }else if(IsEqualGUID(riid, &IID_IActiveScriptError)) {
+        TRACE("(%p)->(IID_IActiveScriptError %p)\n", This, ppv);
+        *ppv = &This->IActiveScriptError_iface;
+    }else {
+        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI JScriptError_AddRef(IActiveScriptError *iface)
+{
+    JScriptError *This = impl_from_IActiveScriptError(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI JScriptError_Release(IActiveScriptError *iface)
+{
+    JScriptError *This = impl_from_IActiveScriptError(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        reset_ei(&This->ei);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI JScriptError_GetExceptionInfo(IActiveScriptError *iface, EXCEPINFO *excepinfo)
+{
+    JScriptError *This = impl_from_IActiveScriptError(iface);
+
+    TRACE("(%p)->(%p)\n", This, excepinfo);
+
+    if(!excepinfo)
+        return E_POINTER;
+
+    memset(excepinfo, 0, sizeof(*excepinfo));
+    excepinfo->scode = This->ei.error;
+    return S_OK;
+}
+
+static HRESULT WINAPI JScriptError_GetSourcePosition(IActiveScriptError *iface, DWORD *source_context, ULONG *line, LONG *character)
+{
+    JScriptError *This = impl_from_IActiveScriptError(iface);
+
+    FIXME("(%p)->(%p %p %p)\n", This, source_context, line, character);
+
+    if(source_context)
+        *source_context = 0;
+    if(line)
+        *line = 0;
+    if(character)
+        *character = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI JScriptError_GetSourceLineText(IActiveScriptError *iface, BSTR *source)
+{
+    JScriptError *This = impl_from_IActiveScriptError(iface);
+
+    FIXME("(%p)->(%p)\n", This, source);
+
+    if(!source)
+        return E_POINTER;
+    *source = NULL;
+    return E_FAIL;
+}
+
+static const IActiveScriptErrorVtbl JScriptErrorVtbl = {
+    JScriptError_QueryInterface,
+    JScriptError_AddRef,
+    JScriptError_Release,
+    JScriptError_GetExceptionInfo,
+    JScriptError_GetSourcePosition,
+    JScriptError_GetSourceLineText
+};
+
 void reset_ei(jsexcept_t *ei)
 {
     ei->error = S_OK;
@@ -121,14 +227,33 @@ void enter_script(script_ctx_t *ctx, jsexcept_t *ei)
 HRESULT leave_script(script_ctx_t *ctx, HRESULT result)
 {
     jsexcept_t *ei = ctx->ei;
+    JScriptError *error;
 
     TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev);
 
     ctx->ei = ei->prev;
-    if(result == DISP_E_EXCEPTION)
+    if(result == DISP_E_EXCEPTION) {
         result = ei->error;
-    if(FAILED(result))
+    }else {
+        reset_ei(ei);
+        ei->error = result;
+    }
+    if(FAILED(result)) {
         WARN("%08x\n", result);
+        if(ctx->site && (error = heap_alloc(sizeof(*error)))) {
+            HRESULT hres;
+
+            error->IActiveScriptError_iface.lpVtbl = &JScriptErrorVtbl;
+            error->ref = 1;
+            error->ei = *ei;
+            memset(ei, 0, sizeof(*ei));
+
+            hres = IActiveScriptSite_OnScriptError(ctx->site, &error->IActiveScriptError_iface);
+            IActiveScriptError_Release(&error->IActiveScriptError_iface);
+            if(hres == S_OK)
+                result = SCRIPT_E_REPORTED;
+        }
+    }
     if(ei->enter_notified && ctx->site)
         IActiveScriptSite_OnLeaveScript(ctx->site);
     reset_ei(ei);
@@ -162,12 +287,14 @@ static void exec_queued_code(JScript *This)
 {
     bytecode_t *iter;
     jsexcept_t ei;
-    HRESULT hres;
+    HRESULT hres = S_OK;
 
     LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) {
         enter_script(This->ctx, &ei);
         hres = exec_source(This->ctx, EXEC_GLOBAL, iter, &iter->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL);
         leave_script(This->ctx, hres);
+        if(FAILED(hres))
+            break;
     }
 
     clear_script_queue(This);
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index ddac4fb904..8b3cc8a1d2 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -2265,9 +2265,10 @@ static void test_error_reports(void)
         script_error = NULL;
         SET_EXPECT(ActiveScriptSite_OnScriptError);
         hres = IActiveScriptParse_ParseScriptText(parser, tests[i].script, NULL, NULL, NULL, 10, 0, 0, NULL, NULL);
-        todo_wine
-        ok(hres == SCRIPT_E_REPORTED || (tests[i].error == JS_E_EXCEPTION_THROWN && hres == SCRIPT_E_PROPAGATE), "[%u] got: 0x%08x\n", i, hres);
-        todo_wine
+        todo_wine_if(tests[i].todo_flags & ERROR_TODO_PARSE)
+        ok(hres == SCRIPT_E_REPORTED || (tests[i].error == JS_E_EXCEPTION_THROWN && hres == SCRIPT_E_PROPAGATE),
+           "[%u] got: 0x%08x for %s\n", i, hres, wine_dbgstr_w(tests[i].script));
+        todo_wine_if(tests[i].todo_flags & ERROR_TODO_PARSE)
         CHECK_CALLED(ActiveScriptSite_OnScriptError);
 
         if (script_error)
@@ -2284,16 +2285,19 @@ static void test_error_reports(void)
             source_context = 0xdeadbeef;
             hres = IActiveScriptError_GetSourcePosition(script_error, &source_context, NULL, NULL);
             ok(hres == S_OK, "GetSourcePosition failed0x%08x\n", hres);
+            todo_wine
             ok(source_context == 10, "source_context = %x\n", source_context);
 
             line_number = 0xdeadbeef;
             hres = IActiveScriptError_GetSourcePosition(script_error, NULL, &line_number, NULL);
             ok(hres == S_OK, "GetSourcePosition failed%08x\n", hres);
+            todo_wine_if(tests[i].line)
             ok(line_number == tests[i].line, "[%u] line = %u expected %u\n", i, line_number, tests[i].line);
 
             character = 0xdeadbeef;
             hres = IActiveScriptError_GetSourcePosition(script_error, NULL, NULL, &character);
             ok(hres == S_OK, "GetSourcePosition failed: %08x\n", hres);
+            todo_wine_if(tests[i].character)
             ok(character == tests[i].character, "[%u] character = %u expected %u\n", i, character, tests[i].character);
 
             hres = IActiveScriptError_GetSourceLineText(script_error, NULL);
@@ -2341,12 +2345,13 @@ static void test_error_reports(void)
             if (is_lang_english())
             {
                 if(tests[i].error_source)
+                    todo_wine
                     ok(ei.bstrSource && !lstrcmpW(ei.bstrSource, tests[i].error_source), "[%u] bstrSource = %s expected %s\n",
                        i, wine_dbgstr_w(ei.bstrSource), wine_dbgstr_w(tests[i].error_source));
                 else
                     ok(!ei.bstrSource, "[%u] bstrSource = %s expected NULL\n", i, wine_dbgstr_w(ei.bstrSource));
                 if(tests[i].description)
-                    todo_wine_if(tests[i].todo_flags & ERROR_TODO_DESCRIPTION)
+                    todo_wine
                     ok(ei.bstrDescription && !lstrcmpW(ei.bstrDescription, tests[i].description),
                        "[%u] bstrDescription = %s expected %s\n", i, wine_dbgstr_w(ei.bstrDescription), wine_dbgstr_w(tests[i].description));
                 else




More information about the wine-cvs mailing list