haikuwebkit/LayoutTests/js/dfg-inline-arguments-use-fr...

210 lines
27 KiB
Plaintext
Raw Permalink Normal View History

All DFG helpers that may call out to arbitrary JS code must know where they were called from due to inlining and call stack walking https://bugs.webkit.org/show_bug.cgi?id=77070 <rdar://problem/10750834> Source/JavaScriptCore: Reviewed by Geoff Garen. Changed the DFG to always record a code origin index in the tag of the argument count (which we previously left blank for the benefit of LLInt, but is still otherwise unused by the DFG), so that if we ever need to walk the stack accurately we know where to start. In particular, if the current ExecState* points several semantic call frames away from the true semantic call frame because we had performed inlining, having the code origin index recorded means that we can reify those call frames as necessary to give runtime/library code an accurate view of the current JS state. This required several large but mechanical changes: - Calling a function from the DFG now plants a store32 instruction to store the code origin index. But the indices of code origins were previously picked by the DFG::JITCompiler after code generation completed. I changed this somewhat; even though the code origins are put into the CodeBlock after code gen, the code gen now knows a priori what their indices will be. Extensive assertions are in place to ensure that the two don't get out of sync, in the form of the DFG::CallBeginToken. Note that this mechanism has almost no effect on JS calls; those don't need the code origin index set in the call frame because we can get it by doing a binary search on the return PC. - Stack walking now always calls trueCallFrame() first before beginning the walk, since even the top call frame may be wrong. It still calls trueCallerFrame() as before to get to the next frame, though trueCallerFrame() is now mostly a wrapper around callerFrame()->trueCallFrame(). - Because the mechanism for getting the code origin of a call frame is bimodal (either the call frame knows its code origin because the code origin index was set, or it's necessary to use the callee frame's return PC), I put in extra mechanisms to determine whether your caller, or your callee, corresponds to a call out of C++ code. Previously we just had the host call flag, but this is insufficient as it does not cover the case of someone calling JSC::call(). But luckily we can determine this just by looking at the return PC: if the return PC is in range of the ctiTrampiline, then two things are true: this call frame's PC will tell you nothing about where you came from in your caller, and the caller already knows where it's at because it must have set the code origin index (unless it's not DFG code, in which case we don't care because there is no inlining to worry about). - During testing this revealed a simple off-by-one goof in DFG::ByteCodeParser's inlining code, so I fixed it. - Finally because I was tired of doing random #if's for checking if I should be passing around an Instruction* or a ReturnAddressPtr, I created a class called AbstractPC that holds whatever notion of a PC is appropriate for the current execution environment. It's designed to work gracefully even if both the interpreter and the JIT are compiled in, and should integrate nicely with the LLInt. This is neutral on all benchmarks and fixes some nasty corner-case regressions of evil code that uses combinations of getters/setters and function.arguments. * CMakeLists.txt: * GNUmakefile.list.am: * JavaScriptCore.exp: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * Target.pri: * bytecode/CodeBlock.h: (JSC::CodeBlock::codeOrigin): (CodeBlock): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleInlining): * dfg/DFGJITCompiler.cpp: (JSC::DFG::JITCompiler::link): * dfg/DFGJITCompiler.h: (CallBeginToken): (JSC::DFG::CallBeginToken::CallBeginToken): (JSC::DFG::CallBeginToken::assertCodeOriginIndex): (JSC::DFG::CallBeginToken::assertNoCodeOriginIndex): (DFG): (JSC::DFG::CallExceptionRecord::CallExceptionRecord): (CallExceptionRecord): (JSC::DFG::JITCompiler::JITCompiler): (JITCompiler): (JSC::DFG::JITCompiler::nextCallBeginToken): (JSC::DFG::JITCompiler::beginCall): (JSC::DFG::JITCompiler::notifyCall): (JSC::DFG::JITCompiler::addExceptionCheck): (JSC::DFG::JITCompiler::addFastExceptionCheck): * dfg/DFGOperations.cpp: (): * dfg/DFGRepatch.cpp: (JSC::DFG::tryBuildGetByIDList): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheck): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::emitCall): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::emitCall): * interpreter/AbstractPC.cpp: Added. (JSC): (JSC::AbstractPC::AbstractPC): * interpreter/AbstractPC.h: Added. (JSC): (AbstractPC): (JSC::AbstractPC::AbstractPC): (JSC::AbstractPC::hasJITReturnAddress): (JSC::AbstractPC::jitReturnAddress): (JSC::AbstractPC::hasInterpreterReturnAddress): (JSC::AbstractPC::interpreterReturnAddress): (JSC::AbstractPC::isSet): (JSC::AbstractPC::operator!): (): * interpreter/CallFrame.cpp: (JSC): (JSC::CallFrame::trueCallFrame): (JSC::CallFrame::trueCallerFrame): * interpreter/CallFrame.h: (JSC::ExecState::abstractReturnPC): (JSC::ExecState::codeOriginIndexForDFGWithInlining): (ExecState): (JSC::ExecState::trueCallFrame): (JSC::ExecState::trueCallFrameFromVMCode): * interpreter/Interpreter.cpp: (JSC::Interpreter::retrieveArgumentsFromVMCode): (JSC::Interpreter::retrieveCallerFromVMCode): (JSC::Interpreter::findFunctionCallFrameFromVMCode): * interpreter/Interpreter.h: (Interpreter): (): * jit/JITStubs.cpp: (JSC): (): * jit/JITStubs.h: (JSC): (JSC::returnAddressIsInCtiTrampoline): * runtime/JSFunction.cpp: (JSC::JSFunction::argumentsGetter): (JSC::JSFunction::callerGetter): (JSC::JSFunction::getOwnPropertyDescriptor): LayoutTests: Reviewed by Geoff Garen. * fast/js/dfg-inline-arguments-use-directly-from-inlined-code-expected.txt: Added. * fast/js/dfg-inline-arguments-use-directly-from-inlined-code.html: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places-broken-expected.txt: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places-broken.html: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places-expected.txt: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places.html: Added. * fast/js/dfg-inline-arguments-use-from-getter-expected.txt: Added. * fast/js/dfg-inline-arguments-use-from-getter.html: Added. * fast/js/script-tests/dfg-inline-arguments-use-directly-from-inlined-code.js: Added. (foo): (bar): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-use-from-all-the-places-broken.js: Added. (foo): (fuzz): (getter): (bar): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-use-from-all-the-places.js: Added. (foo): (fuzz): (getter): (bar): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-use-from-getter.js: Added. (foo): (bar): (argsToStr): Canonical link: https://commits.webkit.org/94051@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@106067 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2012-01-27 01:15:16 +00:00
This attempts to test that inlining preserves basic function.arguments functionality when said functionality is used from inside and outside getters and from inlined code, all at once; but it fails at this and instead finds other bugs particularly in the DFG stack layout machinery.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Fixed ASSERTION FAILED: callFrame == vm->topCallFrame in JSC::Interpreter::addStackTraceIfNecessary https://bugs.webkit.org/show_bug.cgi?id=118498 Patch by Chris Curtis <chris_curtis@apple.com> on 2013-07-18 Reviewed by Geoffrey Garen. Source/JavaScriptCore: * jit/JITStubs.cpp: (throwExceptionFromOpCall): Created new throwExceptionFromOpCall that takes in a functor that contains a function pointer (to create the errorObject) instead of a JSValue. Inside of throwExceptionFromOpCall the topCallFrame is being rolled back in order to handle the error throw. By passing the function pointer in, we can defer the creation of the error object until after topCallFrame has been rolled back. This allows the error object to be created with the appropriate top frame. DEFINE_STUB_FUNCTION(void*, stack_check): DEFINE_STUB_FUNCTION(void*, op_call_arityCheck): DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck): DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction): DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct): (JSC::ErrorFunctor::~ErrorFunctor): (JSC::ErrorWithExecFunctor::ErrorWithExecFunctor): (JSC::ErrorWithExecFunctor::operator()): (JSC::ErrorWithExecAndCalleeFunctor::ErrorWithExecAndCalleeFunctor): (JSC::ErrorWithExecAndCalleeFunctor::operator()): (JSC::ErrorWithExceptionFunctor::ErrorWithExceptionFunctor): (JSC::ErrorWithExceptionFunctor::operator()): (JSC::throwExceptionFromOpCall): In order to eliminate the need to duplicate code, an error functor was created for the 3 different throwExceptionFromOpCall handles. 1. The exception needs to be created, and the function pointer takes 1 parameter(callFrame->callerFrame()). 2. The exception needs to be created, and the function pointer takes 2 parameters (callFrame->callerFrame(), callFrame.calleeAsValue()). 3. The exception is already created. In this case, At the time when the error functor is called, vm.exception is returned. * llint/LLIntSlowPaths.cpp: (JSC::LLInt::LLINT_SLOW_PATH_DECL): * runtime/ExceptionHelpers.cpp: (JSC::errorDescriptionForValue): (JSC::createError): (JSC::createInvalidParameterError): (JSC::createNotAConstructorError): (JSC::createNotAFunctionError): (JSC::createNotAnObjectError): * runtime/ExceptionHelpers.h: The function toString() was being used to stringify an object for an exception message. If the user wrote a toString() for that object, then the system would continue to evaluate that code. A new helper function was created to prevent the system to continue execution and exception creation from that execution. LayoutTests: New Tests to see if JSC evaluates user code after exception creation * fast/js/not-a-constructor-to-string-expected.txt: Added. * fast/js/not-a-constructor-to-string.html: Added. * fast/js/not-a-function-to-string-expected.txt: Added. * fast/js/not-a-function-to-string.html: Added. Modified test output of the object that was being evaluated at the time of the error. Only the error message has changed. * fast/dom/MutationObserver/mutation-record-constructor-expected.txt: * fast/dom/NodeList/nodelist-item-call-as-function-expected.txt: * fast/dom/Range/getClientRects-expected.txt: * fast/dom/SelectorAPI/dumpNodeList-almost-strict-expected.txt: * fast/dom/SelectorAPI/dumpNodeList-expected.txt: * fast/dom/call-a-constructor-as-a-function-expected.txt: * fast/dom/setPrimitiveValue-exceptions-expected.txt: * fast/events/window-onerror-exception-in-attr-expected.txt: * fast/forms/select-namedItem-expected.txt: * fast/js/arguments-expected.txt: * fast/js/array-prototype-properties-expected.txt: * fast/js/basic-strict-mode-expected.txt: * fast/js/date-toisostring-expected.txt: * fast/js/delete-getters-setters-expected.txt: * fast/js/dfg-check-structure-elimination-for-non-cell-expected.txt: * fast/js/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object-expected.txt: * fast/js/dfg-compare-final-object-to-final-object-or-other-when-proven-final-object-expected.txt: * fast/js/dfg-inline-arguments-use-from-all-the-places-broken-expected.txt: * fast/js/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object-expected.txt: * fast/js/dfg-peephole-compare-final-object-to-final-object-or-other-when-proven-final-object-expected.txt: * fast/js/exception-expression-offset-expected.txt: * fast/js/exception-for-nonobject-expected.txt: * fast/js/exception-thrown-from-new-expected.txt: * fast/js/function-bind-expected.txt: * fast/js/instance-of-immediates-expected.txt: * fast/js/object-prototype-properties-expected.txt: * fast/regex/cross-frame-callable-expected.txt: * fast/xsl/transform-xhr-doc-expected.txt: * http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write-expected.txt: * http/tests/security/aboutBlank/xss-DENIED-navigate-opener-javascript-url-expected.txt: * http/tests/security/aboutBlank/xss-DENIED-set-opener-expected.txt: * http/tests/security/document-all-expected.txt: * http/tests/security/srcdoc-in-sandbox-cannot-access-parent-expected.txt: * http/tests/security/window-named-proto-expected.txt: * inspector/console/console-exception-stack-traces-expected.txt: * platform/efl/css3/selectors3/xhtml/css3-modsel-15c-expected.txt: * platform/efl/css3/selectors3/xml/css3-modsel-15c-expected.txt: * platform/efl/fast/events/updateLayoutForHitTest-expected.txt: * platform/efl/tables/mozilla_expected_failures/bugs/bug92868_1-expected.txt: * platform/gtk/css3/selectors3/xhtml/css3-modsel-15c-expected.txt: * platform/gtk/css3/selectors3/xml/css3-modsel-15c-expected.txt: * platform/gtk/fast/events/updateLayoutForHitTest-expected.txt: * platform/gtk/svg/custom/createelement-expected.txt: * platform/gtk/tables/mozilla_expected_failures/bugs/bug92868_1-expected.txt: * platform/mac-wk2/editing/spelling/markers-expected.txt: * platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-expected.txt: Added. * platform/mac-wk2/plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt: Added. * platform/mac/css3/selectors3/xhtml/css3-modsel-15c-expected.txt: * platform/mac/css3/selectors3/xml/css3-modsel-15c-expected.txt: * platform/mac/fast/events/updateLayoutForHitTest-expected.txt: * platform/mac/tables/mozilla_expected_failures/bugs/bug92868_1-expected.txt: * platform/qt/css3/selectors3/xhtml/css3-modsel-15c-expected.txt: * platform/qt/css3/selectors3/xml/css3-modsel-15c-expected.txt: * platform/qt/svg/custom/createelement-expected.txt: * platform/qt/tables/mozilla_expected_failures/bugs/bug92868_1-expected.txt: * platform/win/fast/dom/call-a-constructor-as-a-function-expected.txt: * plugins/npruntime/object-from-destroyed-plugin-expected.txt: * plugins/npruntime/object-from-destroyed-plugin-in-subframe-expected.txt: * plugins/npruntime/plugin-scriptable-object-invoke-default-expected.txt: * sputnik/Conformance/08_Types/8.6_The_Object_Type/8.6.2_Internal_Properties_and_Methods/S8.6.2_A7-expected.txt: * sputnik/Conformance/13_Function_Definition/S13_A17_T2-expected.txt: * sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A1_T1-expected.txt: * sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A1_T2-expected.txt: * sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/S15.1_A2_T1-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.2_Object.prototype.toString/S15.2.4.2_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.3_Object.prototype.toLocaleString/S15.2.4.3_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.4_Object.prototype.valueOf/S15.2.4.4_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.5_Object.prototype.hasOwnProperty/S15.2.4.5_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.6_Object.prototype.isPrototypeOf/S15.2.4.6_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.7_Object.prototype.propertyIsEnumerable/S15.2.4.7_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A3-expected.txt: * sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/S15.2.4_A4-expected.txt: * sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.2_Function.prototype.toString/S15.3.4.2_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/S15.3.4_A5-expected.txt: * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.17_String.prototype.toLocaleLowerCase/S15.5.4.17_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A7-expected.txt: * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A7-expected.txt: * svg/custom/createelement-expected.txt: * svg/custom/use-nested-missing-target-removed-expected.txt: * svg/dom/svgpath-out-of-bounds-getPathSeg-expected.txt: Canonical link: https://commits.webkit.org/136732@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@152871 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2013-07-18 23:24:13 +00:00
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
PASS argsToStr(bar("a" + __i, "b" + __i, "c" + __i)) threw exception TypeError: undefined is not an object (evaluating 'args.length').
All DFG helpers that may call out to arbitrary JS code must know where they were called from due to inlining and call stack walking https://bugs.webkit.org/show_bug.cgi?id=77070 <rdar://problem/10750834> Source/JavaScriptCore: Reviewed by Geoff Garen. Changed the DFG to always record a code origin index in the tag of the argument count (which we previously left blank for the benefit of LLInt, but is still otherwise unused by the DFG), so that if we ever need to walk the stack accurately we know where to start. In particular, if the current ExecState* points several semantic call frames away from the true semantic call frame because we had performed inlining, having the code origin index recorded means that we can reify those call frames as necessary to give runtime/library code an accurate view of the current JS state. This required several large but mechanical changes: - Calling a function from the DFG now plants a store32 instruction to store the code origin index. But the indices of code origins were previously picked by the DFG::JITCompiler after code generation completed. I changed this somewhat; even though the code origins are put into the CodeBlock after code gen, the code gen now knows a priori what their indices will be. Extensive assertions are in place to ensure that the two don't get out of sync, in the form of the DFG::CallBeginToken. Note that this mechanism has almost no effect on JS calls; those don't need the code origin index set in the call frame because we can get it by doing a binary search on the return PC. - Stack walking now always calls trueCallFrame() first before beginning the walk, since even the top call frame may be wrong. It still calls trueCallerFrame() as before to get to the next frame, though trueCallerFrame() is now mostly a wrapper around callerFrame()->trueCallFrame(). - Because the mechanism for getting the code origin of a call frame is bimodal (either the call frame knows its code origin because the code origin index was set, or it's necessary to use the callee frame's return PC), I put in extra mechanisms to determine whether your caller, or your callee, corresponds to a call out of C++ code. Previously we just had the host call flag, but this is insufficient as it does not cover the case of someone calling JSC::call(). But luckily we can determine this just by looking at the return PC: if the return PC is in range of the ctiTrampiline, then two things are true: this call frame's PC will tell you nothing about where you came from in your caller, and the caller already knows where it's at because it must have set the code origin index (unless it's not DFG code, in which case we don't care because there is no inlining to worry about). - During testing this revealed a simple off-by-one goof in DFG::ByteCodeParser's inlining code, so I fixed it. - Finally because I was tired of doing random #if's for checking if I should be passing around an Instruction* or a ReturnAddressPtr, I created a class called AbstractPC that holds whatever notion of a PC is appropriate for the current execution environment. It's designed to work gracefully even if both the interpreter and the JIT are compiled in, and should integrate nicely with the LLInt. This is neutral on all benchmarks and fixes some nasty corner-case regressions of evil code that uses combinations of getters/setters and function.arguments. * CMakeLists.txt: * GNUmakefile.list.am: * JavaScriptCore.exp: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * Target.pri: * bytecode/CodeBlock.h: (JSC::CodeBlock::codeOrigin): (CodeBlock): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleInlining): * dfg/DFGJITCompiler.cpp: (JSC::DFG::JITCompiler::link): * dfg/DFGJITCompiler.h: (CallBeginToken): (JSC::DFG::CallBeginToken::CallBeginToken): (JSC::DFG::CallBeginToken::assertCodeOriginIndex): (JSC::DFG::CallBeginToken::assertNoCodeOriginIndex): (DFG): (JSC::DFG::CallExceptionRecord::CallExceptionRecord): (CallExceptionRecord): (JSC::DFG::JITCompiler::JITCompiler): (JITCompiler): (JSC::DFG::JITCompiler::nextCallBeginToken): (JSC::DFG::JITCompiler::beginCall): (JSC::DFG::JITCompiler::notifyCall): (JSC::DFG::JITCompiler::addExceptionCheck): (JSC::DFG::JITCompiler::addFastExceptionCheck): * dfg/DFGOperations.cpp: (): * dfg/DFGRepatch.cpp: (JSC::DFG::tryBuildGetByIDList): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheck): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::emitCall): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::emitCall): * interpreter/AbstractPC.cpp: Added. (JSC): (JSC::AbstractPC::AbstractPC): * interpreter/AbstractPC.h: Added. (JSC): (AbstractPC): (JSC::AbstractPC::AbstractPC): (JSC::AbstractPC::hasJITReturnAddress): (JSC::AbstractPC::jitReturnAddress): (JSC::AbstractPC::hasInterpreterReturnAddress): (JSC::AbstractPC::interpreterReturnAddress): (JSC::AbstractPC::isSet): (JSC::AbstractPC::operator!): (): * interpreter/CallFrame.cpp: (JSC): (JSC::CallFrame::trueCallFrame): (JSC::CallFrame::trueCallerFrame): * interpreter/CallFrame.h: (JSC::ExecState::abstractReturnPC): (JSC::ExecState::codeOriginIndexForDFGWithInlining): (ExecState): (JSC::ExecState::trueCallFrame): (JSC::ExecState::trueCallFrameFromVMCode): * interpreter/Interpreter.cpp: (JSC::Interpreter::retrieveArgumentsFromVMCode): (JSC::Interpreter::retrieveCallerFromVMCode): (JSC::Interpreter::findFunctionCallFrameFromVMCode): * interpreter/Interpreter.h: (Interpreter): (): * jit/JITStubs.cpp: (JSC): (): * jit/JITStubs.h: (JSC): (JSC::returnAddressIsInCtiTrampoline): * runtime/JSFunction.cpp: (JSC::JSFunction::argumentsGetter): (JSC::JSFunction::callerGetter): (JSC::JSFunction::getOwnPropertyDescriptor): LayoutTests: Reviewed by Geoff Garen. * fast/js/dfg-inline-arguments-use-directly-from-inlined-code-expected.txt: Added. * fast/js/dfg-inline-arguments-use-directly-from-inlined-code.html: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places-broken-expected.txt: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places-broken.html: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places-expected.txt: Added. * fast/js/dfg-inline-arguments-use-from-all-the-places.html: Added. * fast/js/dfg-inline-arguments-use-from-getter-expected.txt: Added. * fast/js/dfg-inline-arguments-use-from-getter.html: Added. * fast/js/script-tests/dfg-inline-arguments-use-directly-from-inlined-code.js: Added. (foo): (bar): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-use-from-all-the-places-broken.js: Added. (foo): (fuzz): (getter): (bar): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-use-from-all-the-places.js: Added. (foo): (fuzz): (getter): (bar): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-use-from-getter.js: Added. (foo): (bar): (argsToStr): Canonical link: https://commits.webkit.org/94051@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@106067 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2012-01-27 01:15:16 +00:00
PASS successfullyParsed is true
TEST COMPLETE