[PATCH 1/2] jscript: Handle detached scope objects 'this' in Object.toString.

Gabriel Ivăncescu gabrielopcode at gmail.com
Wed May 4 11:10:48 CDT 2022


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 at 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;");
-- 
2.34.1




More information about the wine-devel mailing list