diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 8b121747fef..2fa171764bc 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 66dbccfbc0b..685fbd362fd 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -18,6 +18,7 @@ #include +#include #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 bd1f45b9408..2b5f3894caa 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 1c85691edd8..93c6f92baed 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 4812a066d15..be0d0d2fa10 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;");