Jacek Caban : jscript: Suport generic error object for exception with no associated JavaScript exception value.
Alexandre Julliard
julliard at winehq.org
Sun Feb 2 12:56:45 CST 2020
Module: wine
Branch: master
Commit: f6c5da47f7555dfb0762becdf7245d7db8a22062
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f6c5da47f7555dfb0762becdf7245d7db8a22062
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Jan 31 17:22:42 2020 +0100
jscript: Suport generic error object for exception with no associated JavaScript exception value.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/jscript/engine.c | 18 +++++++----
dlls/jscript/error.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/jscript/global.c | 2 +-
dlls/jscript/jscript.h | 1 +
dlls/jscript/tests/lang.js | 31 ++++++++++++++++++
5 files changed, 125 insertions(+), 7 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 8b121747fe..2fa171764b 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -2753,8 +2753,8 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0};
WARN("Exception %08x %s", exception_hres, debugstr_jsval(ei->valid_value ? ei->value : jsval_undefined()));
- if(ei->valid_value && jsval_type(ctx->ei->value) == JSV_OBJECT) {
- error_obj = to_jsdisp(get_object(ctx->ei->value));
+ if(ei->valid_value && jsval_type(ei->value) == JSV_OBJECT) {
+ error_obj = to_jsdisp(get_object(ei->value));
if(error_obj) {
hres = jsdisp_propget_name(error_obj, messageW, &msg);
if(SUCCEEDED(hres)) {
@@ -2768,6 +2768,9 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
print_backtrace(ctx);
}
+ if(exception_hres != DISP_E_EXCEPTION)
+ ei->error = exception_hres;
+
for(frame = ctx->call_ctx; !frame->except_frame; frame = ctx->call_ctx) {
DWORD flags;
@@ -2779,7 +2782,7 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
flags = frame->flags;
pop_call_frame(ctx);
if(!(flags & EXEC_RETURN_TO_INTERP))
- return exception_hres;
+ return DISP_E_EXCEPTION;
}
except_frame = frame->except_frame;
@@ -2792,13 +2795,16 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
scope_pop(&frame->scope);
frame->ip = catch_off ? catch_off : except_frame->finally_off;
- if(catch_off) assert(frame->bytecode->instrs[frame->ip].op == OP_enter_catch);
+ assert(!catch_off || frame->bytecode->instrs[frame->ip].op == OP_enter_catch);
if(ei->valid_value) {
except_val = ctx->ei->value;
- ctx->ei->valid_value = FALSE;
+ ei->valid_value = FALSE;
}else {
- except_val = jsval_undefined();
+ jsdisp_t *err;
+ if(!(err = create_builtin_error(ctx)))
+ return E_OUTOFMEMORY;
+ except_val = jsval_obj(err);
}
/* keep current except_frame if we're entering catch block with finally block associated */
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c
index 66dbccfbc0..685fbd362f 100644
--- a/dlls/jscript/error.c
+++ b/dlls/jscript/error.c
@@ -18,6 +18,7 @@
#include <math.h>
+#include <assert.h>
#include "jscript.h"
#include "engine.h"
@@ -444,3 +445,82 @@ HRESULT throw_uri_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
{
return throw_error(ctx, error, str, ctx->uri_error_constr);
}
+
+jsdisp_t *create_builtin_error(script_ctx_t *ctx)
+{
+ jsdisp_t *constr = ctx->error_constr, *r;
+ jsexcept_t *ei = ctx->ei;
+ HRESULT hres;
+
+ assert(FAILED(ei->error) && ei->error != DISP_E_EXCEPTION);
+
+ if(is_jscript_error(ei->error)) {
+ switch(ei->error) {
+ case JS_E_SYNTAX:
+ case JS_E_MISSING_SEMICOLON:
+ case JS_E_MISSING_LBRACKET:
+ case JS_E_MISSING_RBRACKET:
+ case JS_E_EXPECTED_IDENTIFIER:
+ case JS_E_EXPECTED_ASSIGN:
+ case JS_E_INVALID_CHAR:
+ case JS_E_UNTERMINATED_STRING:
+ case JS_E_MISPLACED_RETURN:
+ case JS_E_INVALID_BREAK:
+ case JS_E_INVALID_CONTINUE:
+ case JS_E_LABEL_REDEFINED:
+ case JS_E_LABEL_NOT_FOUND:
+ case JS_E_EXPECTED_CCEND:
+ case JS_E_DISABLED_CC:
+ case JS_E_EXPECTED_AT:
+ constr = ctx->syntax_error_constr;
+ break;
+
+ case JS_E_TO_PRIMITIVE:
+ case JS_E_INVALIDARG:
+ case JS_E_OBJECT_REQUIRED:
+ case JS_E_INVALID_PROPERTY:
+ case JS_E_INVALID_ACTION:
+ case JS_E_MISSING_ARG:
+ case JS_E_FUNCTION_EXPECTED:
+ case JS_E_DATE_EXPECTED:
+ case JS_E_NUMBER_EXPECTED:
+ case JS_E_OBJECT_EXPECTED:
+ case JS_E_UNDEFINED_VARIABLE:
+ case JS_E_BOOLEAN_EXPECTED:
+ case JS_E_VBARRAY_EXPECTED:
+ case JS_E_INVALID_DELETE:
+ case JS_E_JSCRIPT_EXPECTED:
+ case JS_E_ENUMERATOR_EXPECTED:
+ case JS_E_ARRAY_EXPECTED:
+ case JS_E_NONCONFIGURABLE_REDEFINED:
+ case JS_E_NONWRITABLE_MODIFIED:
+ case JS_E_PROP_DESC_MISMATCH:
+ case JS_E_INVALID_WRITABLE_PROP_DESC:
+ constr = ctx->type_error_constr;
+ break;
+
+ case JS_E_SUBSCRIPT_OUT_OF_RANGE:
+ case JS_E_FRACTION_DIGITS_OUT_OF_RANGE:
+ case JS_E_PRECISION_OUT_OF_RANGE:
+ case JS_E_INVALID_LENGTH:
+ constr = ctx->range_error_constr;
+ break;
+
+ case JS_E_ILLEGAL_ASSIGN:
+ constr = ctx->reference_error_constr;
+ break;
+
+ case JS_E_REGEXP_SYNTAX:
+ constr = ctx->regexp_error_constr;
+ break;
+
+ case JS_E_INVALID_URI_CODING:
+ case JS_E_INVALID_URI_CHAR:
+ constr = ctx->uri_error_constr;
+ break;
+ }
+ }
+
+ hres = create_error(ctx, constr, ei->error, jsstr_empty(), &r);
+ return SUCCEEDED(hres) ? r : NULL;
+}
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index bd1f45b940..2b5f3894ca 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -207,7 +207,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
hres = compile_script(ctx, src, 0, 0, NULL, NULL, TRUE, FALSE, &code);
if(FAILED(hres)) {
WARN("parse (%s) failed: %08x\n", debugstr_jsval(argv[0]), hres);
- return throw_syntax_error(ctx, hres, NULL);
+ return hres;
}
if(!frame || (frame->flags & EXEC_GLOBAL))
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 1c85691edd..93c6f92bae 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -320,6 +320,7 @@ HRESULT throw_regexp_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
HRESULT throw_syntax_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
HRESULT throw_type_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
HRESULT throw_uri_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
+jsdisp_t *create_builtin_error(script_ctx_t *ctx) DECLSPEC_HIDDEN;
HRESULT create_object(script_ctx_t*,jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
HRESULT create_math(script_ctx_t*,jsdisp_t**) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 4812a066d1..be0d0d2fa1 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -1186,6 +1186,37 @@ case 3:
expect(ret, "try");
})();
+(function() {
+ var e;
+ var E_FAIL = -2147467259;
+ var JS_E_SUBSCRIPT_OUT_OF_RANGE = -2146828279;
+
+ try {
+ throwInt(E_FAIL);
+ }catch(ex) {
+ e = ex;
+ }
+ ok(e.name === "Error", "e.name = " + e.name);
+ ok(e.message === "", "e.message = " + e.message);
+ ok(e.number === E_FAIL, "e.number = " + e.number);
+
+ try {
+ throwInt(JS_E_SUBSCRIPT_OUT_OF_RANGE);
+ }catch(ex) {
+ e = ex;
+ }
+ ok(e.name === "RangeError", "e.name = " + e.name);
+ ok(e.number === JS_E_SUBSCRIPT_OUT_OF_RANGE, "e.number = " + e.number);
+
+ try {
+ throwEI(JS_E_SUBSCRIPT_OUT_OF_RANGE);
+ }catch(ex) {
+ e = ex;
+ }
+ ok(e.name === "RangeError", "e.name = " + e.name);
+ ok(e.number === JS_E_SUBSCRIPT_OUT_OF_RANGE, "e.number = " + e.number);
+})();
+
tmp = eval("1");
ok(tmp === 1, "eval(\"1\") !== 1");
eval("{ ok(tmp === 1, 'eval: tmp !== 1'); } tmp = 2;");
More information about the wine-cvs
mailing list