Title: [155075] trunk/Source
Revision
155075
Author
[email protected]
Date
2013-09-04 15:33:57 -0700 (Wed, 04 Sep 2013)

Log Message

Refining the StackIterator callback interface.
https://bugs.webkit.org/show_bug.cgi?id=120695.

Reviewed by Geoffrey Garen.

Source/_javascript_Core: 

Introduce CallFrame::iterate() which instantiates a StackIterator and
invoke its iterate() method with the passed in functor. The only place
where the client code gets access to the StackIterator now is as an
argument to the client's functor.

* API/JSContextRef.cpp:
(JSContextCreateBacktrace):
* interpreter/CallFrame.cpp:
* interpreter/CallFrame.h:
(JSC::ExecState::iterate):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::dumpRegisters):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::unwind):
* interpreter/StackIterator.cpp:
(JSC::StackIterator::StackIterator):
(DebugPrintFrameFunctor::DebugPrintFrameFunctor):
(DebugPrintFrameFunctor::operator()):
(debugPrintCallFrame):
(debugPrintStack):
* interpreter/StackIterator.h:
(JSC::StackIterator::iterate):
* jsc.cpp:
(functionJSCStack):
* profiler/ProfileGenerator.cpp:
(JSC::ProfileGenerator::addParentForConsoleStart):
* runtime/JSFunction.cpp:
(JSC::retrieveArguments):
(JSC::RetrieveCallerFunctionFunctor::operator()):
(JSC::retrieveCallerFunction):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncProtoGetter):
(JSC::globalFuncProtoSetter):
* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorGetPrototypeOf):

Source/WebCore: 

No new tests.

* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::SendFunctor::SendFunctor):
(WebCore::SendFunctor::line):
(WebCore::SendFunctor::url):
(WebCore::SendFunctor::operator()):
(WebCore::JSXMLHttpRequest::send):
* bindings/js/ScriptCallStackFactory.cpp:
(WebCore::createScriptCallStack):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSContextRef.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/API/JSContextRef.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/API/JSContextRef.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -274,8 +274,7 @@
 
     ASSERT(maxStackSize);
     BacktraceFunctor functor(builder, maxStackSize);
-    StackIterator iter = frame->begin();
-    iter.iterate(functor);
+    frame->iterate(functor);
 
     return OpaqueJSString::create(builder.toString()).leakRef();
 }

Modified: trunk/Source/_javascript_Core/ChangeLog (155074 => 155075)


--- trunk/Source/_javascript_Core/ChangeLog	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-09-04 22:33:57 UTC (rev 155075)
@@ -1,3 +1,46 @@
+2013-09-04  Mark Lam  <[email protected]>
+
+        Refining the StackIterator callback interface.
+        https://bugs.webkit.org/show_bug.cgi?id=120695.
+
+        Reviewed by Geoffrey Garen.
+
+        Introduce CallFrame::iterate() which instantiates a StackIterator and
+        invoke its iterate() method with the passed in functor. The only place
+        where the client code gets access to the StackIterator now is as an
+        argument to the client's functor.
+
+        * API/JSContextRef.cpp:
+        (JSContextCreateBacktrace):
+        * interpreter/CallFrame.cpp:
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::iterate):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::dumpRegisters):
+        (JSC::Interpreter::getStackTrace):
+        (JSC::Interpreter::unwind):
+        * interpreter/StackIterator.cpp:
+        (JSC::StackIterator::StackIterator):
+        (DebugPrintFrameFunctor::DebugPrintFrameFunctor):
+        (DebugPrintFrameFunctor::operator()):
+        (debugPrintCallFrame):
+        (debugPrintStack):
+        * interpreter/StackIterator.h:
+        (JSC::StackIterator::iterate):
+        * jsc.cpp:
+        (functionJSCStack):
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::addParentForConsoleStart):
+        * runtime/JSFunction.cpp:
+        (JSC::retrieveArguments):
+        (JSC::RetrieveCallerFunctionFunctor::operator()):
+        (JSC::retrieveCallerFunction):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncProtoGetter):
+        (JSC::globalFuncProtoSetter):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetPrototypeOf):
+
 2013-09-04  Benjamin Poulain  <[email protected]>
 
         JSGenericTypedArrayViewConstructor.h is referenced twice in the XCode project build section, causing warnings

Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/interpreter/CallFrame.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -97,10 +97,4 @@
     return registers() + codeBlock->m_numCalleeRegisters;
 }
 
-StackIterator CallFrame::begin(StackIterator::FrameFilter filter)
-{
-    ASSERT(this);
-    return StackIterator(this, filter);
-}
-
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.h (155074 => 155075)


--- trunk/Source/_javascript_Core/interpreter/CallFrame.h	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.h	2013-09-04 22:33:57 UTC (rev 155075)
@@ -283,8 +283,15 @@
 #endif
         CallFrame* callerFrameNoFlags() { return callerFrame()->removeHostCallFrameFlag(); }
 
-        JS_EXPORT_PRIVATE StackIterator begin(StackIterator::FrameFilter = 0);
+        // CallFrame::iterate() expects a Functor that implements the following method:
+        //     StackIterator::Status operator()(StackIterator&);
 
+        template <typename Functor> void iterate(Functor& functor)
+        {
+            StackIterator iter(this);
+            iter.iterate<Functor>(functor);
+        }
+
     private:
         static const intptr_t HostCallFrameFlag = 1;
         static const int s_thisArgumentOffset = -1 - JSStack::CallFrameHeaderSize;

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -339,8 +339,7 @@
 #endif
 
     DumpRegisterFunctor functor(it);
-    StackIterator iter = callFrame->begin();
-    iter.iterate(functor);
+    callFrame->iterate(functor);
 
     dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
     ++it;
@@ -552,8 +551,7 @@
         return;
 
     GetStackTraceFunctor functor(vm, results, maxStackSize);
-    StackIterator iter = callFrame->begin();
-    iter.iterate(functor);
+    callFrame->iterate(functor);
 }
 
 JSString* Interpreter::stackTraceAsString(ExecState* exec, Vector<StackFrame> stackTrace)
@@ -640,8 +638,7 @@
     VM& vm = callFrame->vm();
     ASSERT(callFrame == vm.topCallFrame);
     UnwindFunctor functor(callFrame, exceptionValue, isTermination, codeBlock, handler);
-    StackIterator iter = callFrame->begin();
-    iter.iterate(functor);
+    callFrame->iterate(functor);
     if (!handler)
         return 0;
 

Modified: trunk/Source/_javascript_Core/interpreter/StackIterator.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/interpreter/StackIterator.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/interpreter/StackIterator.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -35,33 +35,12 @@
 
 namespace JSC {
 
-StackIterator::StackIterator(CallFrame* startFrame, StackIterator::FrameFilter filter)
+StackIterator::StackIterator(CallFrame* startFrame)
     : m_startFrame(startFrame)
-    , m_filter(filter)
 {
     resetIterator();
 }
 
-size_t StackIterator::numberOfFrames()
-{
-    int savedFrameIndex = m_frame.index();
-    resetIterator();
-    while (m_frame.callFrame())
-        gotoNextFrameWithFilter();
-    size_t numberOfFrames = m_frame.index();
-
-    resetIterator();
-    gotoFrameAtIndex(savedFrameIndex);
-
-    return numberOfFrames;
-}
-
-void StackIterator::gotoFrameAtIndex(size_t index)
-{
-    while (m_frame.callFrame() && (m_frame.index() != index))
-        gotoNextFrameWithFilter();
-}
-
 void StackIterator::gotoNextFrame()
 {
 #if ENABLE(DFG_JIT)
@@ -75,17 +54,6 @@
         readFrame(m_frame.callerFrame());
 }
 
-void StackIterator::gotoNextFrameWithFilter()
-{
-    ASSERT(m_frame.callFrame());
-    while (m_frame.callFrame()) {
-        gotoNextFrame();
-        if (!m_frame.callFrame() || !m_filter || !m_filter(&m_frame))
-            break;
-    }
-    m_frame.m_index++;
-}
-
 void StackIterator::resetIterator()
 {
     m_frame.m_index = 0;
@@ -455,29 +423,42 @@
 void debugPrintCallFrame(JSC::CallFrame*);
 void debugPrintStack(JSC::CallFrame* topCallFrame);
 
-void debugPrintCallFrame(JSC::CallFrame* callFrame)
-{
-    if (!callFrame)
-        return;
-    StackIterator iter = callFrame->begin();
-    iter->print(2);
-}
-
-class DebugPrintStackFunctor {
+class DebugPrintFrameFunctor {
 public:
+    enum Action {
+        PrintOne,
+        PrintAll
+    };
+
+    DebugPrintFrameFunctor(Action action)
+        : m_action(action)
+    {
+    }
+
     StackIterator::Status operator()(StackIterator& iter)
     {
         iter->print(2);
-        return StackIterator::Continue;
+        return m_action == PrintAll ? StackIterator::Continue : StackIterator::Done;
     }
+
+private:
+    Action m_action;
 };
 
+void debugPrintCallFrame(JSC::CallFrame* callFrame)
+{
+    if (!callFrame)
+        return;
+    DebugPrintFrameFunctor functor(DebugPrintFrameFunctor::PrintOne);
+    callFrame->iterate(functor);
+}
+
 void debugPrintStack(JSC::CallFrame* topCallFrame)
 {
     if (!topCallFrame)
         return;
-    DebugPrintStackFunctor functor;
-    StackIterator iter = topCallFrame->begin();
-    iter.iterate(functor);
+    DebugPrintFrameFunctor functor(DebugPrintFrameFunctor::PrintAll);
+    topCallFrame->iterate(functor);
 }
+
 #endif // !NDEBUG

Modified: trunk/Source/_javascript_Core/interpreter/StackIterator.h (155074 => 155075)


--- trunk/Source/_javascript_Core/interpreter/StackIterator.h	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/interpreter/StackIterator.h	2013-09-04 22:33:57 UTC (rev 155075)
@@ -100,14 +100,11 @@
 #if ENABLE(DFG_JIT)
         InlineCallFrame* m_inlineCallFrame;
 #endif
-
         CallFrame* m_callFrame;
 
         friend class StackIterator;
     };
 
-    typedef bool (*FrameFilter)(Frame*);
-
     enum Status {
         Continue = 0,
         Done = 1
@@ -122,21 +119,17 @@
             Status status = functor(*this);
             if (status != Continue)
                 break;
-            gotoNextFrameWithFilter();
+            gotoNextFrame();
         }
     }
 
-    JS_EXPORT_PRIVATE size_t numberOfFrames();
-
     Frame& operator*() { return m_frame; }
     ALWAYS_INLINE Frame* operator->() { return &m_frame; }
 
 private:
-    JS_EXPORT_PRIVATE StackIterator(CallFrame* startFrame, FrameFilter = 0);
+    JS_EXPORT_PRIVATE StackIterator(CallFrame* startFrame);
 
-    void gotoFrameAtIndex(size_t frameIndex);
-    void gotoNextFrame();
-    JS_EXPORT_PRIVATE void gotoNextFrameWithFilter();
+    JS_EXPORT_PRIVATE void gotoNextFrame();
     void resetIterator();
 
     void readFrame(CallFrame*);
@@ -146,7 +139,6 @@
 #endif
 
     CallFrame* m_startFrame;
-    FrameFilter m_filter;
     Frame m_frame;
 
     friend class ExecState;

Modified: trunk/Source/_javascript_Core/jsc.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/jsc.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/jsc.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -349,8 +349,7 @@
     trace.appendLiteral("--> Stack trace:\n");
 
     FunctionJSCStackFunctor functor(trace);
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
+    exec->iterate(functor);
     fprintf(stderr, "%s", trace.toString().utf8().data());
     return JSValue::encode(jsUndefined());
 }

Modified: trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -98,8 +98,7 @@
 void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
 {
     AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
+    exec->iterate(functor);
 
     if (!functor.foundParent()) {
         m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, JSValue(), String(), 0), m_head.get(), m_head.get());

Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -210,8 +210,7 @@
 static JSValue retrieveArguments(ExecState* exec, JSFunction* functionObj)
 {
     RetrieveArgumentsFunctor functor(functionObj);
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
+    exec->iterate(functor);
     return functor.result();
 }
 
@@ -223,13 +222,6 @@
     return retrieveArguments(exec, thisObj);
 }
 
-static bool skipOverBoundFunctions(StackIterator::Frame* frame)
-{
-    JSObject* callee = frame->callee();
-    bool shouldSkip = callee ? callee->inherits(JSBoundFunction::info()) : false;
-    return shouldSkip;
-}
-
 class RetrieveCallerFunctionFunctor {
 public:
     RetrieveCallerFunctionFunctor(JSFunction* functionObj)
@@ -245,6 +237,10 @@
     StackIterator::Status operator()(StackIterator& iter)
     {
         JSObject* callee = iter->callee();
+
+        if (callee && callee->inherits(JSBoundFunction::info()))
+            return StackIterator::Continue;
+
         if (!m_hasFoundFrame && (callee != m_targetCallee))
             return StackIterator::Continue;
 
@@ -269,8 +265,7 @@
 static JSValue retrieveCallerFunction(ExecState* exec, JSFunction* functionObj)
 {
     RetrieveCallerFunctionFunctor functor(functionObj);
-    StackIterator iter = exec->begin(skipOverBoundFunctions);
-    iter.iterate(functor);
+    exec->iterate(functor);
     return functor.result();
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -744,8 +744,7 @@
         return JSValue::encode(exec->thisValue().synthesizePrototype(exec));
 
     GlobalFuncProtoGetterFunctor functor(thisObject);
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
+    exec->iterate(functor);
     return functor.result();
 }
 
@@ -788,8 +787,7 @@
         return JSValue::encode(jsUndefined());
 
     GlobalFuncProtoSetterFunctor functor(thisObject);
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
+    exec->iterate(functor);
     if (!functor.allowsAccess())
         return JSValue::encode(jsUndefined());
 

Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (155074 => 155075)


--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -166,8 +166,7 @@
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested prototype of a value that is not an object.")));
     JSObject* object = asObject(exec->argument(0));
     ObjectConstructorGetPrototypeOfFunctor functor(object);
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
+    exec->iterate(functor);
     return functor.result();
 }
 

Modified: trunk/Source/WebCore/ChangeLog (155074 => 155075)


--- trunk/Source/WebCore/ChangeLog	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/WebCore/ChangeLog	2013-09-04 22:33:57 UTC (rev 155075)
@@ -1,3 +1,21 @@
+2013-09-04  Mark Lam  <[email protected]>
+
+        Refining the StackIterator callback interface.
+        https://bugs.webkit.org/show_bug.cgi?id=120695.
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests.
+
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::SendFunctor::SendFunctor):
+        (WebCore::SendFunctor::line):
+        (WebCore::SendFunctor::url):
+        (WebCore::SendFunctor::operator()):
+        (WebCore::JSXMLHttpRequest::send):
+        * bindings/js/ScriptCallStackFactory.cpp:
+        (WebCore::createScriptCallStack):
+
 2013-09-04  Andreas Kling  <[email protected]>
 
         Remove unnecessary RenderView.h inclusion from headers.

Modified: trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp (155074 => 155075)


--- trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -116,26 +116,32 @@
 public:
     SendFunctor()
         : m_hasSkippedFirstFrame(false)
-        , m_hasViableFrame(false)
+        , m_line(0)
     {
     }
 
-    bool hasViableFrame() const { return m_hasViableFrame; }
+    unsigned line() const { return m_line; }
+    String url() const { return m_url; }
 
-    StackIterator::Status operator()(StackIterator&)
+    StackIterator::Status operator()(StackIterator& iter)
     {
         if (!m_hasSkippedFirstFrame) {
             m_hasSkippedFirstFrame = true;
             return StackIterator::Continue;
         }
 
-        m_hasViableFrame = true;
+        unsigned line = 0;
+        unsigned unusedColumn = 0;
+        iter->computeLineAndColumn(line, unusedColumn);
+        m_line = line;
+        m_url = iter->sourceURL();
         return StackIterator::Done;
     }
 
 private:
     bool m_hasSkippedFirstFrame;
-    bool m_hasViableFrame;
+    unsigned m_line;
+    String m_url;
 };
 
 JSValue JSXMLHttpRequest::send(ExecState* exec)
@@ -165,18 +171,9 @@
     }
 
     SendFunctor functor;
-    StackIterator iter = exec->begin();
-    iter.iterate(functor);
-    if (functor.hasViableFrame()) {
-        unsigned line = 0;
-        unsigned unusuedColumn = 0;
-        iter->computeLineAndColumn(line, unusuedColumn);
-        impl()->setLastSendLineNumber(line);
-        impl()->setLastSendURL(iter->sourceURL());
-    } else {
-        impl()->setLastSendLineNumber(0);
-        impl()->setLastSendURL(String());
-    }
+    exec->iterate(functor);
+    impl()->setLastSendLineNumber(functor.line());
+    impl()->setLastSendURL(functor.url());
     setDOMException(exec, ec);
     return jsUndefined();
 }

Modified: trunk/Source/WebCore/bindings/js/ScriptCallStackFactory.cpp (155074 => 155075)


--- trunk/Source/WebCore/bindings/js/ScriptCallStackFactory.cpp	2013-09-04 22:28:36 UTC (rev 155074)
+++ trunk/Source/WebCore/bindings/js/ScriptCallStackFactory.cpp	2013-09-04 22:33:57 UTC (rev 155075)
@@ -87,8 +87,7 @@
     if (JSC::ExecState* exec = JSMainThreadExecState::currentState()) {
         CallFrame* frame = exec->vm().topCallFrame;
         CreateScriptCallStackFunctor functor(frames, maxStackSize);
-        StackIterator iter = frame->begin();
-        iter.iterate(functor);
+        frame->iterate(functor);
     }
     if (frames.isEmpty() && !emptyIsAllowed) {
         // No frames found. It may happen in the case where
@@ -144,10 +143,12 @@
     Vector<ScriptCallFrame> frames;
     ASSERT(exec);
     CallFrame* frame = exec->vm().topCallFrame;
-    StackIterator iter = frame->begin();
-    size_t numberOfFrames = iter.numberOfFrames();
-    CreateScriptCallStackForConsoleFunctor functor(numberOfFrames > 1, maxStackSize, frames);
-    iter.iterate(functor);
+    CreateScriptCallStackForConsoleFunctor functor(true, maxStackSize, frames);
+    frame->iterate(functor);
+    if (frames.isEmpty()) {
+        CreateScriptCallStackForConsoleFunctor functor(false, maxStackSize, frames);
+        frame->iterate(functor);
+    }
     return ScriptCallStack::create(frames);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to