Jacek Caban : jscript: Use proper object as 'this' when function is called on an activation object.

Alexandre Julliard julliard at winehq.org
Wed Nov 14 13:17:16 CST 2012


Module: wine
Branch: master
Commit: 55f0663e3e5bc1c1a7cb460f4e75775f9cc0501b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=55f0663e3e5bc1c1a7cb460f4e75775f9cc0501b

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Nov 14 15:49:46 2012 +0100

jscript: Use proper object as 'this' when function is called on an activation object.

---

 dlls/jscript/engine.c      |   12 ++++++++++++
 dlls/jscript/object.c      |    5 ++++-
 dlls/jscript/tests/lang.js |    6 ++++++
 dlls/jscript/tests/run.c   |    4 ++++
 4 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 44c8333..f4dcc0f 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -292,6 +292,18 @@ HRESULT create_exec_ctx(script_ctx_t *script_ctx, IDispatch *this_obj, jsdisp_t
     ctx->ref = 1;
     ctx->is_global = is_global;
 
+    /* ECMA-262 3rd Edition    11.2.3.7 */
+    if(this_obj) {
+        jsdisp_t *jsthis;
+
+        jsthis = iface_to_jsdisp((IUnknown*)this_obj);
+        if(jsthis) {
+            if(jsthis->builtin_info->class == JSCLASS_GLOBAL || jsthis->builtin_info->class == JSCLASS_NONE)
+                this_obj = NULL;
+            jsdisp_release(jsthis);
+        }
+    }
+
     if(this_obj)
         ctx->this_obj = this_obj;
     else if(script_ctx->host_global)
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
index 34c572f..8047d3f 100644
--- a/dlls/jscript/object.c
+++ b/dlls/jscript/object.c
@@ -16,6 +16,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <assert.h>
+
 #include "jscript.h"
 
 #include "wine/debug.h"
@@ -51,7 +53,7 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
     static const WCHAR regexpW[] = {'R','e','g','E','x','p',0};
     static const WCHAR stringW[] = {'S','t','r','i','n','g',0};
     /* Keep in sync with jsclass_t enum */
-    static const WCHAR *names[] = {objectW, arrayW, booleanW, dateW, errorW,
+    static const WCHAR *names[] = {NULL, arrayW, booleanW, dateW, errorW,
         functionW, NULL, mathW, numberW, objectW, regexpW, stringW, objectW, objectW};
 
     TRACE("\n");
@@ -62,6 +64,7 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
     }else if(names[jsdisp->builtin_info->class]) {
         str = names[jsdisp->builtin_info->class];
     }else {
+        assert(jsdisp->builtin_info->class != JSCLASS_NONE);
         FIXME("jdisp->builtin_info->class = %d\n", jsdisp->builtin_info->class);
         return E_FAIL;
     }
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index ffb5e2e..4f5f29c 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -56,6 +56,9 @@ ok(0 == false, "0 == false is false");
 ok(1 != 2, "1 != 2 is false");
 ok(false != 1, "false != 1 is false");
 
+ok(this === test, "this !== test");
+eval('ok(this === test, "this !== test");');
+
 var trueVar = true;
 ok(trueVar, "trueVar is not true");
 
@@ -71,6 +74,9 @@ function testFunc1(x, y) {
     ok(arguments.callee === testFunc1, "arguments.calee !== testFunc1");
     ok(testFunc1.arguments === arguments, "testFunc1.arguments = " + testFunc1.arguments);
 
+    ok(this === test, "this !== test");
+    eval('ok(this === test, "this !== test");');
+
     return true;
 }
 
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index f0aff60..cacad25 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -1815,6 +1815,10 @@ static BOOL run_tests(void)
 
     parse_script_a("testThis(this);");
     parse_script_a("(function () { testThis(this); })();");
+    parse_script_a("function x() { testThis(this); }; x();");
+    parse_script_a("var t = {func: function () { ok(this === t, 'this !== t'); }}; with(t) { func(); }");
+    parse_script_a("function x() { testThis(this); }; with({y: 1}) { x(); }");
+    parse_script_a("(function () { function x() { testThis(this);} x(); })();");
 
     SET_EXPECT(testobj_onlydispid_d);
     SET_EXPECT(testobj_onlydispid_i);




More information about the wine-cvs mailing list