forked from Mirrors/wine-wine
jscript: Suport generic error object for exception with no associated JavaScript exception value.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
a0e4dbcfd5
commit
f6c5da47f7
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;");
|
||||
|
|
Loading…
Reference in New Issue