GetMyArgumentByVal in FTL
https://bugs.webkit.org/show_bug.cgi?id=128850

Reviewed by Oliver Hunt.
        
This would have been easy if the OSR exit compiler's arity checks hadn't been wrong.
They checked arity by doing "exec->argumentCount == codeBlock->numParameters", which
caused it to think that the arity check had failed if the caller had passed more
arguments than needed. This would cause the call frame copying to sort of go into
reverse (because the amount-by-which-we-failed-arity would have opposite sign,
throwing off a bunch of math) and the stack would end up being corrupted.
        
The bug was revealed by two existing tests although as far as I could tell, neither
test was intending to cover this case directly. So, I added a new test.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
(JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated):
(JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLState.h:
* tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js: Added.
* tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js: Added.
* tests/stress/ftl-get-my-argument-by-val-inlined.js: Added.
* tests/stress/ftl-get-my-argument-by-val.js: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@165072 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js b/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js
new file mode 100644
index 0000000..a178253
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js
@@ -0,0 +1,12 @@
+function foo(i) {
+    return arguments[i];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var thingies = [i % 4, "one", 2, "three"];
+    var result = foo(i % 4, "one", 2, "three");
+    if (result != thingies[i % 4])
+        throw "Error: bad result for i = " + i + ": " + result;
+}