Strict and sloppy functions shouldn't share structure
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@225273 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index b384c71..46fe130 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,52 @@
+2017-11-28 JF Bastien <jfbastien@apple.com>
+
+ Strict and sloppy functions shouldn't share structure
+ https://bugs.webkit.org/show_bug.cgi?id=180103
+ <rdar://problem/35667847>
+
+ Reviewed by Saam Barati.
+
+ * stress/get-by-id-strict-arguments.js: Added. Used to not throw
+ because the IC was wrong.
+ (foo):
+ (bar):
+ (baz):
+ (catch):
+ * stress/get-by-id-strict-callee.js: Added. Not strictly necessary
+ in this patch, but may as well test odd strict mode corner cases.
+ (bar):
+ (baz):
+ (catch):
+ * stress/get-by-id-strict-caller.js: Added. Also IC'd wrong.
+ (foo):
+ (bar):
+ (baz):
+ (catch):
+ * stress/get-by-id-strict-nested-arguments-2.js: Added. Same as
+ next file, but with invalidation of the FunctionExecutable's
+ singletonFunction() to hit SpeculativeJIT::compileNewFunction's
+ slower path.
+ (foo):
+ (bar.const.x):
+ (bar.const.y):
+ (bar):
+ (catch):
+ * stress/get-by-id-strict-nested-arguments.js: Added. Make sure
+ strict nesting works correctly.
+ (foo):
+ (bar.baz):
+ (bar):
+ * stress/strict-function-structure.js: Added. The test used to
+ assert in objectProtoFuncHasOwnProperty.
+ (foo):
+ (bar):
+ (baz):
+ * stress/strict-nested-function-structure.js: Added. Nesting.
+ (foo):
+ (bar):
+ (baz.boo):
+ (baz):
+
2017-11-29 Robin Morisset <rmorisset@apple.com>
The recursive tail call optimisation is wrong on closures
diff --git a/JSTests/stress/get-by-id-strict-arguments.js b/JSTests/stress/get-by-id-strict-arguments.js
new file mode 100644
index 0000000..f5607f4
--- /dev/null
+++ b/JSTests/stress/get-by-id-strict-arguments.js
@@ -0,0 +1,28 @@
+let warm = 1000;
+
+function foo(f) {
+ return f.arguments;
+}
+noInline(foo);
+
+function bar() {
+ for (let i = 0; i < warm; ++i)
+ foo(bar);
+}
+function baz() {
+ "use strict";
+ foo(baz);
+}
+
+bar();
+
+let caught = false;
+
+try {
+ baz();
+} catch (e) {
+ caught = true;
+}
+
+if (!caught)
+ throw new Error(`bad!`);
diff --git a/JSTests/stress/get-by-id-strict-callee.js b/JSTests/stress/get-by-id-strict-callee.js
new file mode 100644
index 0000000..929d65e
--- /dev/null
+++ b/JSTests/stress/get-by-id-strict-callee.js
@@ -0,0 +1,24 @@
+let warm = 1000;
+
+function bar() {
+ for (let i = 0; i < warm; ++i)
+ arguments.callee;
+}
+
+function baz() {
+ "use strict";
+ arguments.callee;
+}
+
+bar();
+
+let caught = false;
+
+try {
+ baz();
+} catch (e) {
+ caught = true;
+}
+
+if (!caught)
+ throw new Error(`bad!`);
diff --git a/JSTests/stress/get-by-id-strict-caller.js b/JSTests/stress/get-by-id-strict-caller.js
new file mode 100644
index 0000000..3462ec0
--- /dev/null
+++ b/JSTests/stress/get-by-id-strict-caller.js
@@ -0,0 +1,28 @@
+let warm = 1000;
+
+function foo(f) {
+ return f.caller;
+}
+noInline(foo);
+
+function bar() {
+ for (let i = 0; i < warm; ++i)
+ foo(bar);
+}
+function baz() {
+ "use strict";
+ foo(baz);
+}
+
+bar();
+
+let caught = false;
+
+try {
+ baz();
+} catch (e) {
+ caught = true;
+}
+
+if (!caught)
+ throw new Error(`bad!`);
diff --git a/JSTests/stress/get-by-id-strict-nested-arguments-2.js b/JSTests/stress/get-by-id-strict-nested-arguments-2.js
new file mode 100644
index 0000000..fdfc9a8
--- /dev/null
+++ b/JSTests/stress/get-by-id-strict-nested-arguments-2.js
@@ -0,0 +1,42 @@
+let warm = 1000;
+
+function foo(f) {
+ return f.arguments;
+}
+noInline(foo);
+
+let caught = 0;
+
+function bar() {
+ for (let i = 0; i < warm; ++i)
+ foo(bar);
+ const x = function baz1() { "use strict"; return 42; };
+ const y = function baz2() { "use strict"; return 0xc0defefe; };
+ return [x, y];
+}
+
+bar();
+bar();
+const [baz1, baz2] = bar();
+
+
+if (baz1() !== 42)
+ throw new Error(`bad!`);
+
+if (baz2() !== 0xc0defefe)
+ throw new Error(`bad!`);
+
+try {
+ foo(baz1);
+} catch (e) {
+ ++caught;
+}
+
+try {
+ foo(baz2);
+} catch (e) {
+ ++caught;
+}
+
+if (caught !== 2)
+ throw new Error(`bad!`);
diff --git a/JSTests/stress/get-by-id-strict-nested-arguments.js b/JSTests/stress/get-by-id-strict-nested-arguments.js
new file mode 100644
index 0000000..0d3ceed
--- /dev/null
+++ b/JSTests/stress/get-by-id-strict-nested-arguments.js
@@ -0,0 +1,27 @@
+let warm = 1000;
+
+function foo(f) {
+ return f.arguments;
+}
+noInline(foo);
+
+let caught = false;
+
+function bar() {
+ for (let i = 0; i < warm; ++i)
+ foo(bar);
+ function baz() {
+ "use strict";
+ try {
+ foo(baz);
+ } catch (e) {
+ caught = true;
+ }
+ }
+ baz();
+}
+
+bar();
+
+if (!caught)
+ throw new Error(`bad!`);
diff --git a/JSTests/stress/strict-function-structure.js b/JSTests/stress/strict-function-structure.js
new file mode 100644
index 0000000..2d5ef71
--- /dev/null
+++ b/JSTests/stress/strict-function-structure.js
@@ -0,0 +1,8 @@
+function foo(f) { f.hasOwnProperty("arguments"); }
+noInline(foo);
+
+function bar() {}
+foo(bar);
+
+function baz() { "use strict"; }
+foo(baz);
diff --git a/JSTests/stress/strict-nested-function-structure.js b/JSTests/stress/strict-nested-function-structure.js
new file mode 100644
index 0000000..ef9d235
--- /dev/null
+++ b/JSTests/stress/strict-nested-function-structure.js
@@ -0,0 +1,12 @@
+function foo(f) { f.hasOwnProperty("arguments"); }
+noInline(foo);
+
+function bar() {}
+foo(bar);
+
+function baz() {
+ "use strict";
+ function boo() {}
+ return boo;
+}
+foo(baz());