From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/json.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/dlls/jscript/json.c b/dlls/jscript/json.c index 7826000f87d..e07ad863348 100644 --- a/dlls/jscript/json.c +++ b/dlls/jscript/json.c @@ -396,13 +396,11 @@ static HRESULT JSON_parse(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned
if(SUCCEEDED(hres)) { struct transform_json_object_ctx proc_ctx = { ctx, get_object(argv[1]), S_OK }; - if(!(str = jsstr_alloc(L""))) - hres = E_OUTOFMEMORY; - else { - ret = transform_json_object(&proc_ctx, root, str); - jsstr_release(str); - hres = proc_ctx.hres; - } + + str = jsstr_empty(); + ret = transform_json_object(&proc_ctx, root, str); + jsstr_release(str); + hres = proc_ctx.hres; } jsdisp_release(root); if(FAILED(hres))
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 49 ++++++++++++++++++++++++++++++- dlls/jscript/tests/api.js | 1 + dlls/mshtml/tests/documentmode.js | 21 +++++++++++++ dlls/mshtml/tests/es5.js | 12 ++++++++ 4 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 83dbfed6054..abd6638cab8 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -270,6 +270,26 @@ HRESULT Function_invoke(jsdisp_t *func_this, jsval_t vthis, WORD flags, unsigned return function->vtbl->call(function->dispex.ctx, function, vthis, flags, argc, argv, r); }
+static HRESULT Function_get_caller(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + FunctionInstance *function = function_from_jsdisp(jsthis); + call_frame_t *frame; + + TRACE("%p\n", jsthis); + + for(frame = ctx->call_ctx; frame; frame = frame->prev_frame) { + if(frame->function_instance == &function->dispex) { + if(!frame->prev_frame || !frame->prev_frame->function_instance) + break; + *r = jsval_obj(jsdisp_addref(frame->prev_frame->function_instance)); + return S_OK; + } + } + + *r = jsval_null(); + return S_OK; +} + static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) { TRACE("%p\n", jsthis); @@ -565,6 +585,7 @@ static const builtin_prop_t Function_props[] = { {L"arguments", NULL, 0, Function_get_arguments}, {L"bind", Function_bind, PROPF_METHOD|PROPF_ES5|1}, {L"call", Function_call, PROPF_METHOD|1}, + {L"caller", NULL, PROPF_HTML, Function_get_caller}, {L"length", NULL, 0, Function_get_length}, {L"toString", Function_toString, PROPF_METHOD} }; @@ -584,6 +605,7 @@ static const builtin_info_t Function_info = {
static const builtin_prop_t FunctionInst_props[] = { {L"arguments", NULL, 0, Function_get_arguments}, + {L"caller", NULL, PROPF_HTML, Function_get_caller}, {L"length", NULL, 0, Function_get_length} };
@@ -769,6 +791,7 @@ static HRESULT InterpretedFunction_set_prototype(script_ctx_t *ctx, jsdisp_t *js
static const builtin_prop_t InterpretedFunction_props[] = { {L"arguments", NULL, 0, Function_get_arguments}, + {L"caller", NULL, PROPF_HTML, Function_get_caller}, {L"length", NULL, 0, Function_get_length}, {L"prototype", NULL, 0, InterpretedFunction_get_prototype, InterpretedFunction_set_prototype} }; @@ -889,6 +912,30 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod return S_OK; }
+static HRESULT BindFunction_get_caller(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + return JS_E_INVALID_ACTION; +} + +static const builtin_prop_t BindFunction_props[] = { + {L"arguments", NULL, 0, Function_get_arguments}, + {L"caller", NULL, 0, BindFunction_get_caller}, + {L"length", NULL, 0, Function_get_length} +}; + +static const builtin_info_t BindFunction_info = { + JSCLASS_FUNCTION, + Function_value, + ARRAY_SIZE(BindFunction_props), + BindFunction_props, + Function_destructor, + NULL, + NULL, + NULL, + NULL, + Function_gc_traverse +}; + static HRESULT BindFunction_call(script_ctx_t *ctx, FunctionInstance *func, jsval_t vthis, unsigned flags, unsigned argc, jsval_t *argv, jsval_t *r) { @@ -975,7 +1022,7 @@ static HRESULT create_bind_function(script_ctx_t *ctx, FunctionInstance *target, BindFunction *function; HRESULT hres;
- hres = create_function(ctx, NULL, &BindFunctionVtbl, FIELD_OFFSET(BindFunction, args[argc]), PROPF_METHOD, + hres = create_function(ctx, &BindFunction_info, &BindFunctionVtbl, FIELD_OFFSET(BindFunction, args[argc]), PROPF_METHOD, FALSE, NULL, (void**)&function); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 481e0612be5..a7a6f5a0ac2 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -286,6 +286,7 @@ ok(unescape(escape(tmp)) === tmp, "unescape(escape('" + tmp + "')) = " + unescap ok(Object.prototype.hasOwnProperty('toString'), "Object.prototype.hasOwnProperty('toString') is false"); ok(Object.prototype.hasOwnProperty('isPrototypeOf'), "Object.prototype.hasOwnProperty('isPrototypeOf') is false"); ok(Function.prototype.hasOwnProperty('call'), "Function.prototype.hasOwnProperty('call') is false"); +ok(!Function.prototype.hasOwnProperty('caller'), "Function.prototype.hasOwnProperty('caller') is true");
Object(); new Object(); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 9007d451bdb..dd67a117e64 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -840,6 +840,27 @@ sync_test("for..in", function() { ok(found === 1, "ondragstart enumerated " + found + " times in document after set to empty string"); });
+sync_test("function caller", function() { + ok(Function.prototype.hasOwnProperty("caller"), "caller not prop of Function.prototype"); + + function test_caller(expected_caller, stop) { + ok(test_caller.caller === expected_caller, "caller = " + test_caller.caller); + if(stop) return; + function nested() { + ok(nested.caller === test_caller, "nested caller = " + nested.caller); + test_caller(nested, true); + ok(test_caller.caller === expected_caller, "caller within nested = " + test_caller.caller); + } + nested(); + ok(test_caller.caller === expected_caller, "caller after nested = " + test_caller.caller); + } + ok(test_caller.hasOwnProperty("caller"), "caller not prop of test_caller"); + ok(test_caller.caller === null, "test_caller.caller = " + test_caller.caller); + + function f1() { test_caller(f1); } f1(); + function f2() { test_caller(f2); } f2(); +}); + sync_test("elem_by_id", function() { document.body.innerHTML = '<form id="testid" name="testname"></form>'; var v = document.documentMode, found, i; diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 1ed3a64bcba..43723a68d00 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -18,6 +18,7 @@
var E_INVALIDARG = 0x80070057; var JS_E_PROP_DESC_MISMATCH = 0x800a01bd; +var JS_E_INVALID_ACTION = 0x800a01bd; var JS_E_NUMBER_EXPECTED = 0x800a1389; var JS_E_FUNCTION_EXPECTED = 0x800a138a; var JS_E_DATE_EXPECTED = 0x800a138e; @@ -525,11 +526,14 @@ sync_test("getOwnPropertyDescriptor", function() { (function() { test_own_data_prop_desc(arguments, "length", true, false, true); test_own_data_prop_desc(arguments, "callee", true, false, true); + ok(!("caller" in arguments), "caller in arguments"); })();
test_own_data_prop_desc(String, "prototype", false, false, false); test_own_data_prop_desc(function(){}, "prototype", true, false, false); + test_own_data_prop_desc(function(){}, "caller", false, false, false); test_own_data_prop_desc(Function, "prototype", false, false, false); + test_own_data_prop_desc(Function.prototype, "caller", false, false, false); test_own_data_prop_desc(String.prototype, "constructor", true, false, true);
try { @@ -1136,6 +1140,14 @@ sync_test("bind", function() { r = f.call(o2); ok(r === 1, "r = " + r);
+ try { + f.caller; + ok(false, "expected exception getting f.caller"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_INVALID_ACTION, "f.caller threw " + n); + } + f = (function() { ok(this === o, "this != o"); ok(arguments.length === 1, "arguments.length = " + arguments.length);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 7 ++++++- dlls/mshtml/tests/es5.js | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index abd6638cab8..c4ee495a428 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -912,13 +912,18 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod return S_OK; }
+static HRESULT BindFunction_get_arguments(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + return JS_E_INVALID_ACTION; +} + static HRESULT BindFunction_get_caller(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) { return JS_E_INVALID_ACTION; }
static const builtin_prop_t BindFunction_props[] = { - {L"arguments", NULL, 0, Function_get_arguments}, + {L"arguments", NULL, 0, BindFunction_get_arguments}, {L"caller", NULL, 0, BindFunction_get_caller}, {L"length", NULL, 0, Function_get_length} }; diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 43723a68d00..fb9b710c70c 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -532,8 +532,10 @@ sync_test("getOwnPropertyDescriptor", function() { test_own_data_prop_desc(String, "prototype", false, false, false); test_own_data_prop_desc(function(){}, "prototype", true, false, false); test_own_data_prop_desc(function(){}, "caller", false, false, false); + test_own_data_prop_desc(function(){}, "arguments", false, false, false); test_own_data_prop_desc(Function, "prototype", false, false, false); test_own_data_prop_desc(Function.prototype, "caller", false, false, false); + test_own_data_prop_desc(Function.prototype, "arguments", false, false, false); test_own_data_prop_desc(String.prototype, "constructor", true, false, true);
try { @@ -1140,6 +1142,13 @@ sync_test("bind", function() { r = f.call(o2); ok(r === 1, "r = " + r);
+ try { + f.arguments; + ok(false, "expected exception getting f.arguments"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_INVALID_ACTION, "f.arguments threw " + n); + } try { f.caller; ok(false, "expected exception getting f.caller");
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 2 +- dlls/jscript/tests/api.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index c4ee495a428..a0450c57fe4 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -582,7 +582,7 @@ static HRESULT Function_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op o
static const builtin_prop_t Function_props[] = { {L"apply", Function_apply, PROPF_METHOD|2}, - {L"arguments", NULL, 0, Function_get_arguments}, + {L"arguments", NULL, PROPF_HTML, Function_get_arguments}, {L"bind", Function_bind, PROPF_METHOD|PROPF_ES5|1}, {L"call", Function_call, PROPF_METHOD|1}, {L"caller", NULL, PROPF_HTML, Function_get_caller}, diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index a7a6f5a0ac2..d632d889476 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -287,6 +287,7 @@ ok(Object.prototype.hasOwnProperty('toString'), "Object.prototype.hasOwnProperty ok(Object.prototype.hasOwnProperty('isPrototypeOf'), "Object.prototype.hasOwnProperty('isPrototypeOf') is false"); ok(Function.prototype.hasOwnProperty('call'), "Function.prototype.hasOwnProperty('call') is false"); ok(!Function.prototype.hasOwnProperty('caller'), "Function.prototype.hasOwnProperty('caller') is true"); +ok(!Function.prototype.hasOwnProperty('arguments'), "Function.prototype.hasOwnProperty('arguments') is true");
Object(); new Object();
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 2 +- dlls/jscript/engine.h | 2 +- dlls/jscript/function.c | 37 ++++++++++++++++++++++++------------- 3 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index d2b1089b8ac..379d209f0b0 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -3116,7 +3116,7 @@ static void pop_call_frame(script_ctx_t *ctx) }
if(frame->arguments_obj) - detach_arguments_object(frame->arguments_obj); + detach_arguments_object(frame); if(frame->scope) scope_release(frame->scope);
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 917f67c17d8..68b60401063 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -310,4 +310,4 @@ HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain
HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN; HRESULT setup_arguments_object(script_ctx_t*,call_frame_t*) DECLSPEC_HIDDEN; -void detach_arguments_object(jsdisp_t*) DECLSPEC_HIDDEN; +void detach_arguments_object(call_frame_t*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index a0450c57fe4..4942c70e75e 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -66,7 +66,7 @@ typedef struct { typedef struct { jsdisp_t jsdisp; jsval_t *buf; - call_frame_t *frame; + scope_chain_t *scope; unsigned argc; } ArgumentsInstance;
@@ -113,6 +113,9 @@ static void Arguments_destructor(jsdisp_t *jsdisp) free(arguments->buf); }
+ if(arguments->scope) + scope_release(arguments->scope); + free(arguments); }
@@ -126,9 +129,9 @@ static jsval_t *get_argument_ref(ArgumentsInstance *arguments, unsigned idx) { if(arguments->buf) return arguments->buf + idx; - if(!arguments->frame->base_scope->detached_vars) - return arguments->jsdisp.ctx->stack + arguments->frame->arguments_off + idx; - return arguments->frame->base_scope->detached_vars->var + idx; + if(!arguments->scope->detached_vars) + return arguments->jsdisp.ctx->stack + arguments->scope->frame->arguments_off + idx; + return arguments->scope->detached_vars->var + idx; }
static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) @@ -172,6 +175,12 @@ static HRESULT Arguments_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op } }
+ if(arguments->scope) { + hres = gc_process_linked_obj(gc_ctx, op, jsdisp, &arguments->scope->dispex, (void**)&arguments->scope); + if(FAILED(hres)) + return hres; + } + return S_OK; }
@@ -203,7 +212,7 @@ HRESULT setup_arguments_object(script_ctx_t *ctx, call_frame_t *frame) }
args->argc = frame->argc; - args->frame = frame; + args->scope = scope_addref(frame->base_scope);
hres = jsdisp_define_data_property(&args->jsdisp, L"length", PROPF_WRITABLE | PROPF_CONFIGURABLE, jsval_number(args->argc)); @@ -221,23 +230,22 @@ HRESULT setup_arguments_object(script_ctx_t *ctx, call_frame_t *frame) return S_OK; }
-void detach_arguments_object(jsdisp_t *args_disp) +void detach_arguments_object(call_frame_t *frame) { - ArgumentsInstance *arguments = arguments_from_jsdisp(args_disp); - call_frame_t *frame = arguments->frame; - const BOOL on_stack = frame->base_scope->frame == frame; - jsdisp_t *jsobj = as_jsdisp(frame->base_scope->obj); + ArgumentsInstance *arguments = arguments_from_jsdisp(frame->arguments_obj); + scope_chain_t *scope = arguments->scope; + const BOOL on_stack = scope->frame == frame; + jsdisp_t *jsobj = as_jsdisp(scope->obj);
/* Reset arguments value to cut the reference cycle. Note that since all activation contexts have * their own arguments property, it's impossible to use prototype's one during name lookup */ jsdisp_propput_name(jsobj, L"arguments", jsval_undefined()); - arguments->frame = NULL;
/* Don't bother coppying arguments if call frame holds the last reference. */ if(arguments->jsdisp.ref > 1) { arguments->buf = malloc(arguments->argc * sizeof(*arguments->buf)); if(arguments->buf) { - const jsval_t *args = on_stack ? arguments->jsdisp.ctx->stack + frame->arguments_off : frame->base_scope->detached_vars->var; + const jsval_t *args = on_stack ? arguments->jsdisp.ctx->stack + frame->arguments_off : scope->detached_vars->var; int i;
for(i = 0; i < arguments->argc ; i++) { @@ -248,9 +256,12 @@ void detach_arguments_object(jsdisp_t *args_disp) ERR("out of memory\n"); arguments->argc = 0; } + + arguments->scope = NULL; + scope_release(scope); }
- jsdisp_release(frame->arguments_obj); + jsdisp_release(&arguments->jsdisp); }
HRESULT Function_invoke(jsdisp_t *func_this, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 2 +- dlls/mshtml/tests/documentmode.js | 50 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 4942c70e75e..68f841b38a1 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -242,7 +242,7 @@ void detach_arguments_object(call_frame_t *frame) jsdisp_propput_name(jsobj, L"arguments", jsval_undefined());
/* Don't bother coppying arguments if call frame holds the last reference. */ - if(arguments->jsdisp.ref > 1) { + if(arguments->jsdisp.ref > 1 && !arguments->jsdisp.ctx->html_mode) { arguments->buf = malloc(arguments->argc * sizeof(*arguments->buf)); if(arguments->buf) { const jsval_t *args = on_stack ? arguments->jsdisp.ctx->stack + frame->arguments_off : scope->detached_vars->var; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index dd67a117e64..3533d721960 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1228,6 +1228,56 @@ sync_test("delete_prop", function() { ok(!("globalprop4" in obj), "globalprop4 is still in obj"); });
+sync_test("detached arguments", function() { + var args, get_a, set_a, get_x, set_x; + + function test_args() { + ok(args[0] === 1, "args[0] = " + args[0]); + set_x(2); + ok(args[0] === 2, "args[0] = " + args[0]); + args[0] = 3; + ok(get_x() === 3, "get_x() = " + get_x()); + ok(args[0] === 3, "args[0] = " + args[0]); + } + + (function(x) { + args = arguments; + get_x = function() { return x; }; + set_x = function(v) { x = v; }; + + test_args(); + x = 1; + })(1); + test_args(); + + (function(a, a, b, c) { + get_a = function() { return a; } + set_a = function(v) { a = v; } + ok(get_a() === 2, "get_a() = " + get_a()); + ok(a === 2, "a = " + a); + ok(b === 3, "b = " + b); + ok(c === 4, "c = " + c); + a = 42; + ok(arguments[0] === 1, "arguments[0] = " + arguments[0]); + ok(arguments[1] === 42, "arguments[1] = " + arguments[1]); + ok(get_a() === 42, "get_a() after assign = " + get_a()); + args = arguments; + })(1, 2, 3, 4); + + ok(get_a() === 42, "get_a() after detach = " + get_a()); + set_a(100); + ok(get_a() === 100, "get_a() after set_a() = " + get_a()); + ok(args[0] === 1, "detached args[0] = " + args[0]); + ok(args[1] === 100, "detached args[1] = " + args[1]); + + (function(a, a) { + eval("var a = 7;"); + ok(a === 7, "function(a, a) a = " + a); + ok(arguments[0] === 5, "function(a, a) arguments[0] = " + arguments[0]); + ok(arguments[1] === 7, "function(a, a) arguments[1] = " + arguments[1]); + })(5, 6); +}); + var func_scope_val = 1; var func_scope_val2 = 2;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
As it is done in exec_source. This matters as we actually have a check in exprval_call that relies on this (because scope variable objects must never be exposed).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 379d209f0b0..1bf5bb77858 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -749,7 +749,7 @@ static HRESULT detach_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_
if (!scope->obj) { - if (FAILED(hres = create_object(ctx, NULL, &jsobj))) + if (FAILED(hres = create_dispex(ctx, NULL, NULL, &jsobj))) return hres; scope->obj = to_disp(jsobj); } @@ -1071,7 +1071,7 @@ static HRESULT scope_init_locals(script_ctx_t *ctx) } else if (!scope->obj) { - if (FAILED(hres = create_object(ctx, NULL, &jsobj))) + if (FAILED(hres = create_dispex(ctx, NULL, NULL, &jsobj))) return hres; scope->obj = to_disp(jsobj); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/number.c | 2 +- dlls/jscript/tests/api.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c index a5ab775a5d5..00456daaf53 100644 --- a/dlls/jscript/number.c +++ b/dlls/jscript/number.c @@ -525,7 +525,7 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, jsval_t vthis, WORD flags, if(FAILED(hres)) return hres;
- if(argc) { + if(argc && (ctx->version < 2 || !is_undefined(argv[0]))) { hres = to_int32(ctx, argv[0], &prec); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index d632d889476..fb98946fdc7 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -1432,6 +1432,10 @@ tmp = (new Number(1.182e30)).toPrecision(5); ok(tmp == "1.1820e+30", "num(1.182e30)).toPrecision(5) = " + tmp); tmp = (new Number(1.123)).toPrecision(); ok(tmp == "1.123", "num(1.123).toPrecision() = " + tmp); +if(invokeVersion >= 2) { + tmp = (new Number(1.123)).toPrecision(undefined); + ok(tmp == "1.123", "num(1.123).toPrecision(undefined) = " + tmp); +}
ok(Number() === 0, "Number() = " + Number()); ok(Number(false) === 0, "Number(false) = " + Number(false)); @@ -2707,6 +2711,8 @@ testException(function() {Number.prototype.toLocaleString.call(null);}, "E_NOT_N testException(function() {(new Number(3)).toString(1);}, "E_INVALID_CALL_ARG"); testException(function() {(new Number(3)).toFixed(21);}, "E_FRACTION_DIGITS_OUT_OF_RANGE"); testException(function() {(new Number(1)).toPrecision(0);}, "E_PRECISION_OUT_OF_RANGE"); +if(invokeVersion < 2) + testException(function() {(new Number(1)).toPrecision(undefined);}, "E_PRECISION_OUT_OF_RANGE"); testException(function() {not_existing_variable.something();}, "E_UNDEFINED"); testException(function() {date();}, "E_NOT_FUNC"); testException(function() {arr();}, "E_NOT_FUNC");
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/number.c | 2 +- dlls/jscript/tests/api.js | 1 + dlls/mshtml/tests/es5.js | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c index 00456daaf53..27c3d5ecfee 100644 --- a/dlls/jscript/number.c +++ b/dlls/jscript/number.c @@ -239,7 +239,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, uns if(FAILED(hres)) return hres;
- if(argc) { + if(argc && (ctx->version < SCRIPTLANGUAGEVERSION_ES5 || !is_undefined(argv[0]))) { hres = to_int32(ctx, argv[0], &radix); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index fb98946fdc7..0fc683c20cb 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -2709,6 +2709,7 @@ testException(function() {Number.prototype.toFixed.call(arr);}, "E_NOT_NUM"); testException(function() {Number.prototype.toLocaleString.call(arr);}, "E_NOT_NUM"); testException(function() {Number.prototype.toLocaleString.call(null);}, "E_NOT_NUM"); testException(function() {(new Number(3)).toString(1);}, "E_INVALID_CALL_ARG"); +testException(function() {(new Number(3)).toString(undefined);}, "E_INVALID_CALL_ARG"); testException(function() {(new Number(3)).toFixed(21);}, "E_FRACTION_DIGITS_OUT_OF_RANGE"); testException(function() {(new Number(1)).toPrecision(0);}, "E_PRECISION_OUT_OF_RANGE"); if(invokeVersion < 2) diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index fb9b710c70c..e86ab1dbe77 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -1127,6 +1127,9 @@ sync_test("toString", function() { obj = Object.create(Number.prototype); tmp = Object.prototype.toString.call(obj); ok(tmp === "[object Object]", "toString.call(Object.create(Number.prototype)) = " + tmp); + + tmp = (new Number(303)).toString(undefined); + ok(tmp === "303", "Number 303 toString(undefined) = " + tmp); });
sync_test("bind", function() {
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=134077
Your paranoid android.
=== w864 (64 bit report) ===
mshtml: script.c:937: Test failed: L"/index.html?xhr.js: async_xhr.readyState = 1" script.c:937: Test failed: L"/index.html?xhr.js: async_xhr.readyState = 1" script.c:937: Test failed: L"/index.html?xhr.js: async_xhr2.readyState = 4" script.c:937: Test failed: L"/index.html?xhr.js: async_xhr2.readyState = 4" script.c:937: Test failed: L"/index.html?xhr.js: unexpected order: 0,1,2,3,sync_xhr(4),nested(4),4,async_xhr2(3),async_xhr2(4),async_xhr(3),async_xhr(4),sync_xhr_in_async,msg1,msg2,msg_sync,msg_nested,msg_async,timeout,timeout_sync,timeout_nested"
=== w10pro64_zh_CN (64 bit report) ===
mshtml: script.c:3761: Test failed: OnResponse failed: 80004004
This merge request was approved by Jacek Caban.