Jacek Caban : jscript: Add GetSourceLineText implementation.

Alexandre Julliard julliard at winehq.org
Tue Feb 4 15:33:21 CST 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb  4 20:28:38 2020 +0100

jscript: Add GetSourceLineText implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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));
             }




More information about the wine-cvs mailing list