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/ftl/FTLOSRExitCompiler.cpp b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
index f8093b1..e81b6b6 100644
--- a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
@@ -249,7 +249,8 @@
jit.add32(
MacroAssembler::TrustedImm32(-codeBlock->numParameters()), GPRInfo::regT2,
GPRInfo::regT3);
- MacroAssembler::Jump arityIntact = jit.branchTest32(MacroAssembler::Zero, GPRInfo::regT3);
+ MacroAssembler::Jump arityIntact = jit.branch32(
+ MacroAssembler::GreaterThanOrEqual, GPRInfo::regT3, MacroAssembler::TrustedImm32(0));
jit.neg32(GPRInfo::regT3);
jit.add32(MacroAssembler::TrustedImm32(1 + stackAlignmentRegisters() - 1), GPRInfo::regT3);
jit.and32(MacroAssembler::TrustedImm32(-stackAlignmentRegisters()), GPRInfo::regT3);
@@ -303,8 +304,10 @@
// We need to make sure that we return into the register restoration thunk. This works
// differently depending on whether or not we had arity issues.
- MacroAssembler::Jump arityIntactForReturnPC =
- jit.branchTest32(MacroAssembler::Zero, GPRInfo::regT3);
+ MacroAssembler::Jump arityIntactForReturnPC = jit.branch32(
+ MacroAssembler::GreaterThanOrEqual,
+ CCallHelpers::payloadFor(JSStack::ArgumentCount),
+ MacroAssembler::TrustedImm32(codeBlock->numParameters()));
// The return PC in the call frame header points at exactly the right arity restoration
// thunk. We don't want to change that. But the arity restoration thunk's frame has a