Object.prototype.toString is unique in that it's a builtin that accepts any value as 'this', even null or undefined or non-JS objects (and returns [object Object] for them). However, for detached scopes, it returns JS_E_OBJECT_EXPECTED. This is important because it shows that builtins don't follow the path specified in `ECMA-262 3rd Edition 11.2.3.7` (which is handled in exec_source now) which would otherwise replace 'this' with null, and toString can handle null just fine.
Without this, the assertion triggers.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Note that ES5 is different (next patch).
dlls/jscript/object.c | 3 ++- dlls/jscript/tests/api.js | 2 ++ dlls/jscript/tests/lang.js | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index a675e45..453ea95 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -73,8 +73,9 @@ static HRESULT Object_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, uns str = L"[object Object]"; }else if(names[jsdisp->builtin_info->class]) { str = names[jsdisp->builtin_info->class]; + }else if(jsdisp->builtin_info->class == JSCLASS_NONE) { + hres = JS_E_OBJECT_EXPECTED; }else { - assert(jsdisp->builtin_info->class != JSCLASS_NONE); FIXME("jsdisp->builtin_info->class = %d\n", jsdisp->builtin_info->class); hres = E_FAIL; } diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index e81bbea..85677a1 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -2634,6 +2634,8 @@ testException(function() {null.toString();}, "E_OBJECT_EXPECTED"); testException(function() {RegExp.prototype.toString.call(new Object());}, "E_REGEXP_EXPECTED"); testException(function() {/a/.lastIndex();}, "E_NOT_FUNC"); testException(function() {"a".length();}, "E_NOT_FUNC"); +testException(function() {((function() { var f = Number.prototype.toString; return (function() { return f(); }); })())();}, "E_NOT_NUM"); +testException(function() {((function() { var f = Object.prototype.toString; return (function() { return f(); }); })())();}, "E_OBJECT_EXPECTED");
testException(function() { return arguments.callee(); }, "E_STACK_OVERFLOW");
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index cf08423..67e4576 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -310,6 +310,9 @@ argumentsTest(); ok(callAsExprTest.arguments === null, "callAsExprTest.arguments = " + callAsExprTest.arguments); })(1,2);
+tmp = ((function() { var f = function() {return this}; return (function() { return f(); }); })())(); +ok(tmp === this, "detached scope function call this != global this"); + tmp = (function() {1;})(); ok(tmp === undefined, "tmp = " + tmp); tmp = eval("1;");