Module: wine Branch: master Commit: 150b7391b878aed21e13116d7628adddabf13c0e URL: https://source.winehq.org/git/wine.git/?a=commit;h=150b7391b878aed21e13116d7...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Feb 4 20:28:38 2020 +0100
jscript: Add GetSourceLineText implementation.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/jscript/compile.c | 2 +- dlls/jscript/engine.c | 2 +- dlls/jscript/engine.h | 3 ++- dlls/jscript/error.c | 4 +++- dlls/jscript/jscript.c | 15 ++++++++++++--- dlls/jscript/parser.y | 18 +++++++++++++++--- dlls/jscript/tests/run.c | 9 +++++++-- 7 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 2be5f24fae..61db10cd41 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -2521,7 +2521,7 @@ HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, UINT64 source_conte if(FAILED(hres)) { if(hres != DISP_E_EXCEPTION) throw_error(ctx, hres, NULL); - set_error_location(ctx->ei, compiler.code, compiler.loc, IDS_COMPILATION_ERROR); + set_error_location(ctx->ei, compiler.code, compiler.loc, IDS_COMPILATION_ERROR, NULL); release_bytecode(compiler.code); return DISP_E_EXCEPTION; } diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 054b0c7602..f94cfd1e80 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2779,7 +2779,7 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres) frame = ctx->call_ctx; if(exception_hres != DISP_E_EXCEPTION) throw_error(ctx, exception_hres, NULL); - set_error_location(ei, frame->bytecode, frame->bytecode->instrs[frame->ip].loc, IDS_RUNTIME_ERROR); + set_error_location(ei, frame->bytecode, frame->bytecode->instrs[frame->ip].loc, IDS_RUNTIME_ERROR, NULL);
while(!frame->except_frame) { DWORD flags; diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index bb991c442e..cad46e12c5 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -229,6 +229,7 @@ struct _jsexcept_t {
jsstr_t *source; jsstr_t *message; + jsstr_t *line;
bytecode_t *code; unsigned loc; @@ -240,7 +241,7 @@ struct _jsexcept_t { void enter_script(script_ctx_t*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT leave_script(script_ctx_t*,HRESULT) DECLSPEC_HIDDEN; void reset_ei(jsexcept_t*) DECLSPEC_HIDDEN; -void set_error_location(jsexcept_t*,bytecode_t*,unsigned,unsigned) DECLSPEC_HIDDEN; +void set_error_location(jsexcept_t*,bytecode_t*,unsigned,unsigned,jsstr_t*) DECLSPEC_HIDDEN;
typedef struct _except_frame_t except_frame_t; struct _parser_ctx_t; diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index eca6c90138..4d54d74f6c 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -420,7 +420,7 @@ HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str) return DISP_E_EXCEPTION; }
-void set_error_location(jsexcept_t *ei, bytecode_t *code, unsigned loc, unsigned source_id) +void set_error_location(jsexcept_t *ei, bytecode_t *code, unsigned loc, unsigned source_id, jsstr_t *line) { if(is_jscript_error(ei->error)) { if(!ei->source) { @@ -438,6 +438,8 @@ void set_error_location(jsexcept_t *ei, bytecode_t *code, unsigned loc, unsigned
ei->code = bytecode_addref(code); ei->loc = loc; + if(line) + ei->line = jsstr_addref(line); }
jsdisp_t *create_builtin_error(script_ctx_t *ctx) diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 860fb01cf5..8f97fa818d 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -211,12 +211,17 @@ static HRESULT WINAPI JScriptError_GetSourceLineText(IActiveScriptError *iface, { JScriptError *This = impl_from_IActiveScriptError(iface);
- FIXME("(%p)->(%p)\n", This, source); + TRACE("(%p)->(%p)\n", This, source);
if(!source) return E_POINTER; - *source = NULL; - return E_FAIL; + + if(!This->ei.line) { + *source = NULL; + return E_FAIL; + } + + return jsstr_to_bstr(This->ei.line, source); }
static const IActiveScriptErrorVtbl JScriptErrorVtbl = { @@ -248,6 +253,10 @@ void reset_ei(jsexcept_t *ei) jsstr_release(ei->message); ei->message = NULL; } + if(ei->line) { + jsstr_release(ei->line); + ei->line = NULL; + } }
void enter_script(script_ctx_t *ctx, jsexcept_t *ei) diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 5a71a84ffa..507369ca20 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1598,12 +1598,24 @@ HRESULT script_parse(script_ctx_t *ctx, struct _compiler_ctx_t *compiler, byteco heap_pool_clear(mark); hres = parser_ctx->hres; if(FAILED(hres)) { - WARN("parser failed around %s\n", - debugstr_w(parser_ctx->begin+20 > parser_ctx->ptr ? parser_ctx->begin : parser_ctx->ptr-20)); + const WCHAR *line_start = code->source + parser_ctx->error_loc, *line_end = line_start; + jsstr_t *line_str; + + while(line_start > code->source && line_start[-1] != '\n') + line_start--; + while(*line_end && *line_end != '\n') + line_end++; + line_str = jsstr_alloc_len(line_start, line_end - line_start); + + WARN("parser failed around %s in line %s\n", + debugstr_w(parser_ctx->begin+20 > parser_ctx->ptr ? parser_ctx->begin : parser_ctx->ptr-20), + debugstr_jsstr(line_str));
throw_error(ctx, hres, NULL); - set_error_location(ctx->ei, code, parser_ctx->error_loc, IDS_COMPILATION_ERROR); + set_error_location(ctx->ei, code, parser_ctx->error_loc, IDS_COMPILATION_ERROR, line_str); parser_release(parser_ctx); + if(line_str) + jsstr_release(line_str); return DISP_E_EXCEPTION; }
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 6e2250882d..675bd819ee 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -2232,6 +2232,13 @@ static void test_error_reports(void) NULL, ERROR_TODO_SCODE | ERROR_TODO_DESCRIPTION }, + { + L"f(1\n,\n2,\n ,,3\n);\n", + JS_E_SYNTAX, 3, 1, + L"Microsoft JScript compilation error", + L"Syntax error", + L" ,,3" + }, };
if (!is_lang_english()) @@ -2304,9 +2311,7 @@ static void test_error_reports(void) hres = IActiveScriptError_GetSourceLineText(script_error, &line_text); if (tests[i].line_text) { - todo_wine ok(hres == S_OK, "GetSourceLineText failed: %08x\n", hres); - todo_wine ok(line_text != NULL && !lstrcmpW(line_text, tests[i].line_text), "[%u] GetSourceLineText returned %s expected %s\n", i, wine_dbgstr_w(line_text), wine_dbgstr_w(tests[i].line_text)); }