2010-10-18  Oliver Hunt  <oliver@apple.com>

        Reviewed by Darin Adler.

        Strict mode: |this| should be undefined if it is not explicitly provided
        https://bugs.webkit.org/show_bug.cgi?id=47833

        To make strict mode behave correctly we want to pass undefined instead of null
        as the default this value.  This has no impact on behaviour outside of strict
        mode as both values are replaced with the global object if necessary.

        * bytecompiler/NodesCodegen.cpp:
        (JSC::FunctionCallValueNode::emitBytecode):
        (JSC::FunctionCallResolveNode::emitBytecode):
        (JSC::CallFunctionCallDotNode::emitBytecode):
        (JSC::ApplyFunctionCallDotNode::emitBytecode):

2010-10-18  Oliver Hunt  <oliver@apple.com>

        Reviewed by Darin Adler.

        Strict mode: |this| should be undefined if it is not explicitly provided
        https://bugs.webkit.org/show_bug.cgi?id=47833

        Add tests to ensure that |this| is undefined rather than null when it has
        not been explicitly provided.

        * fast/js/basic-strict-mode-expected.txt:
        * fast/js/script-tests/basic-strict-mode.js:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69977 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 6651ac1..c0b4edc 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,21 @@
+2010-10-18  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Darin Adler.
+
+        Strict mode: |this| should be undefined if it is not explicitly provided
+        https://bugs.webkit.org/show_bug.cgi?id=47833
+
+        To make strict mode behave correctly we want to pass undefined instead of null
+        as the default this value.  This has no impact on behaviour outside of strict
+        mode as both values are replaced with the global object if necessary.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::FunctionCallValueNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+
+
 2010-10-18  Darin Adler  <darin@apple.com>
 
         Reviewed by Anders Carlsson.
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 5f073a8..449cae9 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -371,7 +371,7 @@
 {
     RefPtr<RegisterID> func = generator.emitNode(m_expr);
     CallArguments callArguments(generator, m_args);
-    generator.emitLoad(callArguments.thisRegister(), jsNull());
+    generator.emitLoad(callArguments.thisRegister(), jsUndefined());
     return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
 }
 
@@ -381,7 +381,7 @@
 {
     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
         CallArguments callArguments(generator, m_args);
-        generator.emitLoad(callArguments.thisRegister(), jsNull());
+        generator.emitLoad(callArguments.thisRegister(), jsUndefined());
         return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), local.get(), callArguments, divot(), startOffset(), endOffset());
     }
 
@@ -392,7 +392,7 @@
     if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         CallArguments callArguments(generator, m_args);
-        generator.emitLoad(callArguments.thisRegister(), jsNull());
+        generator.emitLoad(callArguments.thisRegister(), jsUndefined());
         return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
     }
 
@@ -455,7 +455,7 @@
         } else {
             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
             CallArguments callArguments(generator, m_args);
-            generator.emitLoad(callArguments.thisRegister(), jsNull());
+            generator.emitLoad(callArguments.thisRegister(), jsUndefined());
             generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
             generator.emitJump(end.get());
         }
@@ -513,7 +513,7 @@
             } else {
                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
                 CallArguments callArguments(generator, m_args);
-                generator.emitLoad(callArguments.thisRegister(), jsNull());
+                generator.emitLoad(callArguments.thisRegister(), jsUndefined());
                 generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
             }
         } else {
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2ccf2b3..0a1e706 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2010-10-18  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Darin Adler.
+
+        Strict mode: |this| should be undefined if it is not explicitly provided
+        https://bugs.webkit.org/show_bug.cgi?id=47833
+
+        Add tests to ensure that |this| is undefined rather than null when it has
+        not been explicitly provided.
+
+        * fast/js/basic-strict-mode-expected.txt:
+        * fast/js/script-tests/basic-strict-mode.js:
+
 2010-10-18  Robert Hogan  <robert@webkit.org>
 
         Rubber-stamped by Csaba Osztrogonác.
diff --git a/LayoutTests/fast/js/basic-strict-mode-expected.txt b/LayoutTests/fast/js/basic-strict-mode-expected.txt
index e4c2012..6741c54 100644
--- a/LayoutTests/fast/js/basic-strict-mode-expected.txt
+++ b/LayoutTests/fast/js/basic-strict-mode-expected.txt
@@ -21,7 +21,11 @@
 PASS testThisBracketAccess.call(true, 'length') is undefined.
 PASS testThisBracketAccess.call(false, 'length') is undefined.
 PASS testThisBracketAccess.call(1, 'length') is undefined.
-PASS testGlobalAccess() is null
+PASS testGlobalAccess() is undefined
+PASS testThis.call() is undefined
+PASS testThis.apply() is undefined
+PASS testThis.call(undefined) is undefined
+PASS testThis.apply(undefined) is undefined
 PASS (function eval(){'use strict';}) threw exception SyntaxError: Parse error.
 PASS (function (eval){'use strict';}) threw exception SyntaxError: Parse error.
 PASS (function arguments(){'use strict';}) threw exception SyntaxError: Parse error.
diff --git a/LayoutTests/fast/js/script-tests/basic-strict-mode.js b/LayoutTests/fast/js/script-tests/basic-strict-mode.js
index f6f485d..51b3510 100644
--- a/LayoutTests/fast/js/script-tests/basic-strict-mode.js
+++ b/LayoutTests/fast/js/script-tests/basic-strict-mode.js
@@ -36,7 +36,11 @@
 shouldBeUndefined("testThisBracketAccess.call(1, 'length')");
 
 
-shouldBe("testGlobalAccess()", "null");
+shouldBe("testGlobalAccess()", "undefined");
+shouldBe("testThis.call()", "undefined");
+shouldBe("testThis.apply()", "undefined");
+shouldBe("testThis.call(undefined)", "undefined");
+shouldBe("testThis.apply(undefined)", "undefined");
 
 shouldThrow("(function eval(){'use strict';})");
 shouldThrow("(function (eval){'use strict';})");