Commit 75482382 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Add IActiveScriptError implementation.

parent 33984c39
...@@ -64,6 +64,12 @@ typedef struct { ...@@ -64,6 +64,12 @@ typedef struct {
struct list queued_code; struct list queued_code;
} JScript; } JScript;
typedef struct {
IActiveScriptError IActiveScriptError_iface;
LONG ref;
jsexcept_t ei;
} JScriptError;
void script_release(script_ctx_t *ctx) void script_release(script_ctx_t *ctx)
{ {
if(--ctx->ref) if(--ctx->ref)
...@@ -101,6 +107,106 @@ static inline BOOL is_started(script_ctx_t *ctx) ...@@ -101,6 +107,106 @@ static inline BOOL is_started(script_ctx_t *ctx)
|| ctx->state == SCRIPTSTATE_DISCONNECTED; || 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) void reset_ei(jsexcept_t *ei)
{ {
ei->error = S_OK; ei->error = S_OK;
...@@ -121,14 +227,33 @@ void enter_script(script_ctx_t *ctx, jsexcept_t *ei) ...@@ -121,14 +227,33 @@ void enter_script(script_ctx_t *ctx, jsexcept_t *ei)
HRESULT leave_script(script_ctx_t *ctx, HRESULT result) HRESULT leave_script(script_ctx_t *ctx, HRESULT result)
{ {
jsexcept_t *ei = ctx->ei; jsexcept_t *ei = ctx->ei;
JScriptError *error;
TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev); TRACE("ctx %p ei %p prev %p\n", ctx, ei, ei->prev);
ctx->ei = ei->prev; ctx->ei = ei->prev;
if(result == DISP_E_EXCEPTION) if(result == DISP_E_EXCEPTION) {
result = ei->error; result = ei->error;
if(FAILED(result)) }else {
reset_ei(ei);
ei->error = result;
}
if(FAILED(result)) {
WARN("%08x\n", 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) if(ei->enter_notified && ctx->site)
IActiveScriptSite_OnLeaveScript(ctx->site); IActiveScriptSite_OnLeaveScript(ctx->site);
reset_ei(ei); reset_ei(ei);
...@@ -162,12 +287,14 @@ static void exec_queued_code(JScript *This) ...@@ -162,12 +287,14 @@ static void exec_queued_code(JScript *This)
{ {
bytecode_t *iter; bytecode_t *iter;
jsexcept_t ei; jsexcept_t ei;
HRESULT hres; HRESULT hres = S_OK;
LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) { LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) {
enter_script(This->ctx, &ei); 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); 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); leave_script(This->ctx, hres);
if(FAILED(hres))
break;
} }
clear_script_queue(This); clear_script_queue(This);
......
...@@ -2265,9 +2265,10 @@ static void test_error_reports(void) ...@@ -2265,9 +2265,10 @@ static void test_error_reports(void)
script_error = NULL; script_error = NULL;
SET_EXPECT(ActiveScriptSite_OnScriptError); SET_EXPECT(ActiveScriptSite_OnScriptError);
hres = IActiveScriptParse_ParseScriptText(parser, tests[i].script, NULL, NULL, NULL, 10, 0, 0, NULL, NULL); hres = IActiveScriptParse_ParseScriptText(parser, tests[i].script, NULL, NULL, NULL, 10, 0, 0, NULL, NULL);
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\n", i, hres); ok(hres == SCRIPT_E_REPORTED || (tests[i].error == JS_E_EXCEPTION_THROWN && hres == SCRIPT_E_PROPAGATE),
todo_wine "[%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); CHECK_CALLED(ActiveScriptSite_OnScriptError);
if (script_error) if (script_error)
...@@ -2284,16 +2285,19 @@ static void test_error_reports(void) ...@@ -2284,16 +2285,19 @@ static void test_error_reports(void)
source_context = 0xdeadbeef; source_context = 0xdeadbeef;
hres = IActiveScriptError_GetSourcePosition(script_error, &source_context, NULL, NULL); hres = IActiveScriptError_GetSourcePosition(script_error, &source_context, NULL, NULL);
ok(hres == S_OK, "GetSourcePosition failed0x%08x\n", hres); ok(hres == S_OK, "GetSourcePosition failed0x%08x\n", hres);
todo_wine
ok(source_context == 10, "source_context = %x\n", source_context); ok(source_context == 10, "source_context = %x\n", source_context);
line_number = 0xdeadbeef; line_number = 0xdeadbeef;
hres = IActiveScriptError_GetSourcePosition(script_error, NULL, &line_number, NULL); hres = IActiveScriptError_GetSourcePosition(script_error, NULL, &line_number, NULL);
ok(hres == S_OK, "GetSourcePosition failed%08x\n", hres); 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); ok(line_number == tests[i].line, "[%u] line = %u expected %u\n", i, line_number, tests[i].line);
character = 0xdeadbeef; character = 0xdeadbeef;
hres = IActiveScriptError_GetSourcePosition(script_error, NULL, NULL, &character); hres = IActiveScriptError_GetSourcePosition(script_error, NULL, NULL, &character);
ok(hres == S_OK, "GetSourcePosition failed: %08x\n", hres); 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); ok(character == tests[i].character, "[%u] character = %u expected %u\n", i, character, tests[i].character);
hres = IActiveScriptError_GetSourceLineText(script_error, NULL); hres = IActiveScriptError_GetSourceLineText(script_error, NULL);
...@@ -2341,12 +2345,13 @@ static void test_error_reports(void) ...@@ -2341,12 +2345,13 @@ static void test_error_reports(void)
if (is_lang_english()) if (is_lang_english())
{ {
if(tests[i].error_source) if(tests[i].error_source)
todo_wine
ok(ei.bstrSource && !lstrcmpW(ei.bstrSource, tests[i].error_source), "[%u] bstrSource = %s expected %s\n", 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)); i, wine_dbgstr_w(ei.bstrSource), wine_dbgstr_w(tests[i].error_source));
else else
ok(!ei.bstrSource, "[%u] bstrSource = %s expected NULL\n", i, wine_dbgstr_w(ei.bstrSource)); ok(!ei.bstrSource, "[%u] bstrSource = %s expected NULL\n", i, wine_dbgstr_w(ei.bstrSource));
if(tests[i].description) 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), 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)); "[%u] bstrDescription = %s expected %s\n", i, wine_dbgstr_w(ei.bstrDescription), wine_dbgstr_w(tests[i].description));
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment