<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[185487] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/185487">185487</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2015-06-11 22:39:28 -0700 (Thu, 11 Jun 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
https://bugs.webkit.org/show_bug.cgi?id=145872

Reviewed by Michael Saboff.

Source/JavaScriptCore:

In <a href="http://trac.webkit.org/projects/webkit/changeset/185259">r185259</a>, we changed exception handling code inside the VM to work with
Exception objects instead of the thrown JSValue.  The handling code will get the
exception stack trace from the Exception object.

However, there is some code that cannot be updated to pass the Exception object.
An example of this are the ObjC API functions.  Those functions are specified to
return any thrown exception JSValue in a JSValueRef.  Since these APIs are
public, we cannot arbitrarily change them to use the Exception object.

There are client code that calls these APIs and then passes the returned exception
JSValue to WebCore::reportException() to be reported.  WebCore::reportException()
previously relied on the VM::exceptionStackTrace() to provide a cache of the
stack trace of the last thrown exception.  VM::exceptionStackTrace() no longer
exists in the current code.

To restore this functionality, we will introduce VM::lastException() which
caches the last thrown Exception object.  With this, if the exception passed to
WebCore::reportException() to be reported isn't an Exception object (which has its
own stack trace), reportException() can again use the cached exception stack trace
which is available from VM::lastException().

* heap/Heap.cpp:
(JSC::Heap::visitException):
- visit VM::m_lastException on GCs.

* interpreter/CallFrame.h:
(JSC::ExecState::lastException):
(JSC::ExecState::clearLastException):
- convenience functions to get and clear the last exception.

* runtime/Exception.cpp:
(JSC::Exception::create):
(JSC::Exception::finishCreation):
- add support to create an Exception object without capturing the JS stack trace.
  This is needed for making an Exception object to wrap a thrown value that does
  not have a stack trace.
  Currently, this is only used by WebCore::reportException() when there is no
  Exception object and no last exception available to provide a stack trace.

* runtime/Exception.h:
(JSC::Exception::cast): Deleted.  No longer needed.

* runtime/VM.h:
(JSC::VM::clearLastException):
(JSC::VM::setException):
(JSC::VM::lastException):
(JSC::VM::addressOfLastException):
- Added support for VM::m_lastException.
  VM::m_lastException serves to cache the exception stack of the most recently
  thrown exception like VM::exceptionStackTrace() used to before <a href="http://trac.webkit.org/projects/webkit/changeset/185259">r185259</a>.

* runtime/VMEntryScope.cpp:
(JSC::VMEntryScope::VMEntryScope):
- Clear VM::m_lastException when we re-enter the VM.  Exceptions should have been
  handled before we re-enter the VM anyway.  So, this is a good place to release
  the cached last exception.

  NOTE: this is also where the old code before <a href="http://trac.webkit.org/projects/webkit/changeset/185259">r185259</a> clears the last exception
  stack trace.  So, we're just restoring the previous behavior here in terms of
  the lifecycle of the last exception stack.

Source/WebCore:

API test added: WebKit1.ReportExceptionTest.

* bindings/js/JSDOMBinding.cpp:
(WebCore::reportException):
- Added a version of reportException() that takes a JSValue instead of an Exception
  object.  This version will ensure that we have an Exception object before calling
  into the original reportException() as follows:

  1. If the JSValue is already an Exception object, we're good to go.

  2. Else, if VM::lastException() is available, use that as the exception.
     This is how the old code use to behave (in terms of where it gets the exception
     stack trace).  The assumption is that reportException() will be called in
     a timely manner before the exception stack trace has been purged.

  3. Else, create an Exception object with no stack trace.  This is the fall back
     in case the client did not call reportException() in a timely manner.

- Also clear the last exception after we've reported it.  This is how the old code
  before <a href="http://trac.webkit.org/projects/webkit/changeset/185259">r185259</a> behave (in terms of the lifecycle of the last exception stack
  trace).  We're restoring that behavior here.

* bindings/js/JSDOMBinding.h:

Source/WebKit/mac:

* WebView/WebView.mm:
(+[WebView _reportException:inContext:]):
- Don't assume we have an Exception object.  Let WebCore::reportException() take
  care of it.

Source/WebKit/win:

* WebView.cpp:
(WebView::reportException):
- Don't assume we have an Exception object.  Let WebCore::reportException() take
  care of it.

Source/WebKit2:

* WebProcess/InjectedBundle/InjectedBundle.cpp:
(WebKit::InjectedBundle::reportException):
- Don't assume we have an Exception object.  Let WebCore::reportException() take
  care of it.

Tools:

* TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm:
(-[DidCreateJavaScriptContextFrameLoadDelegate webView:didCreateJavaScriptContext:forFrame:]):
- Exercises the JSC ObjC API to call a function which throws an exception.  That
  exception will be returned as a JSValue instead of an Exception object.  We
  will use this JSValue to test WebCore::reportException() to confirm that it is
  able to handle an exception value which is not an Exception object.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterCallFrameh">trunk/Source/JavaScriptCore/interpreter/CallFrame.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExceptioncpp">trunk/Source/JavaScriptCore/runtime/Exception.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExceptionh">trunk/Source/JavaScriptCore/runtime/Exception.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMEntryScopecpp">trunk/Source/JavaScriptCore/runtime/VMEntryScope.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingcpp">trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingh">trunk/Source/WebCore/bindings/js/JSDOMBinding.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebViewWebViewmm">trunk/Source/WebKit/mac/WebView/WebView.mm</a></li>
<li><a href="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitwinWebViewcpp">trunk/Source/WebKit/win/WebView.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessInjectedBundleInjectedBundlecpp">trunk/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsmacWebViewDidCreateJavaScriptContextmm">trunk/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2015-06-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        In r185259, we changed exception handling code inside the VM to work with
+        Exception objects instead of the thrown JSValue.  The handling code will get the
+        exception stack trace from the Exception object.
+
+        However, there is some code that cannot be updated to pass the Exception object.
+        An example of this are the ObjC API functions.  Those functions are specified to
+        return any thrown exception JSValue in a JSValueRef.  Since these APIs are
+        public, we cannot arbitrarily change them to use the Exception object.
+
+        There are client code that calls these APIs and then passes the returned exception
+        JSValue to WebCore::reportException() to be reported.  WebCore::reportException()
+        previously relied on the VM::exceptionStackTrace() to provide a cache of the
+        stack trace of the last thrown exception.  VM::exceptionStackTrace() no longer
+        exists in the current code.
+
+        To restore this functionality, we will introduce VM::lastException() which
+        caches the last thrown Exception object.  With this, if the exception passed to
+        WebCore::reportException() to be reported isn't an Exception object (which has its
+        own stack trace), reportException() can again use the cached exception stack trace
+        which is available from VM::lastException().
+
+        * heap/Heap.cpp:
+        (JSC::Heap::visitException):
+        - visit VM::m_lastException on GCs.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::lastException):
+        (JSC::ExecState::clearLastException):
+        - convenience functions to get and clear the last exception.
+
+        * runtime/Exception.cpp:
+        (JSC::Exception::create):
+        (JSC::Exception::finishCreation):
+        - add support to create an Exception object without capturing the JS stack trace.
+          This is needed for making an Exception object to wrap a thrown value that does
+          not have a stack trace.
+          Currently, this is only used by WebCore::reportException() when there is no
+          Exception object and no last exception available to provide a stack trace.
+
+        * runtime/Exception.h:
+        (JSC::Exception::cast): Deleted.  No longer needed.
+
+        * runtime/VM.h:
+        (JSC::VM::clearLastException):
+        (JSC::VM::setException):
+        (JSC::VM::lastException):
+        (JSC::VM::addressOfLastException):
+        - Added support for VM::m_lastException.
+          VM::m_lastException serves to cache the exception stack of the most recently
+          thrown exception like VM::exceptionStackTrace() used to before r185259.
+
+        * runtime/VMEntryScope.cpp:
+        (JSC::VMEntryScope::VMEntryScope):
+        - Clear VM::m_lastException when we re-enter the VM.  Exceptions should have been
+          handled before we re-enter the VM anyway.  So, this is a good place to release
+          the cached last exception.
+
+          NOTE: this is also where the old code before r185259 clears the last exception
+          stack trace.  So, we're just restoring the previous behavior here in terms of
+          the lifecycle of the last exception stack.
+
</ins><span class="cx"> 2015-06-11  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         jsSubstring() should support creating substrings from substrings.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -717,10 +717,11 @@
</span><span class="cx"> void Heap::visitException(HeapRootVisitor&amp; visitor)
</span><span class="cx"> {
</span><span class="cx">     GCPHASE(MarkingException);
</span><del>-    if (!m_vm-&gt;exception())
</del><ins>+    if (!m_vm-&gt;exception() &amp;&amp; !m_vm-&gt;lastException())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     visitor.visit(m_vm-&gt;addressOfException());
</span><ins>+    visitor.visit(m_vm-&gt;addressOfLastException());
</ins><span class="cx"> 
</span><span class="cx">     if (Options::logGC() == GCLogging::Verbose)
</span><span class="cx">         dataLog(&quot;Exceptions:\n&quot;, m_slotVisitor);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterCallFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/CallFrame.h (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/CallFrame.h        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/interpreter/CallFrame.h        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -79,6 +79,9 @@
</span><span class="cx">         Exception* exception() const { return vm().exception(); }
</span><span class="cx">         bool hadException() const { return !!vm().exception(); }
</span><span class="cx"> 
</span><ins>+        Exception* lastException() const { return vm().lastException(); }
+        void clearLastException() { vm().clearLastException(); }
+
</ins><span class="cx">         AtomicStringTable* atomicStringTable() const { return vm().atomicStringTable(); }
</span><span class="cx">         const CommonIdentifiers&amp; propertyNames() const { return *vm().propertyNames; }
</span><span class="cx">         const MarkedArgumentBuffer&amp; emptyList() const { return *vm().emptyList; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExceptioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Exception.cpp (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Exception.cpp        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/runtime/Exception.cpp        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -32,10 +32,10 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo Exception::s_info = { &quot;Exception&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(Exception) };
</span><span class="cx"> 
</span><del>-Exception* Exception::create(VM&amp; vm, JSValue thrownValue)
</del><ins>+Exception* Exception::create(VM&amp; vm, JSValue thrownValue, StackCaptureAction action)
</ins><span class="cx"> {
</span><span class="cx">     Exception* result = new (NotNull, allocateCell&lt;Exception&gt;(vm.heap)) Exception(vm);
</span><del>-    result-&gt;finishCreation(vm, thrownValue);
</del><ins>+    result-&gt;finishCreation(vm, thrownValue, action);
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -68,14 +68,15 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Exception::finishCreation(VM&amp; vm, JSValue thrownValue)
</del><ins>+void Exception::finishCreation(VM&amp; vm, JSValue thrownValue, StackCaptureAction action)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm);
</span><span class="cx"> 
</span><span class="cx">     m_value.set(vm, this, thrownValue);
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;StackFrame&gt; stackTrace;
</span><del>-    vm.interpreter-&gt;getStackTrace(stackTrace);
</del><ins>+    if (action == StackCaptureAction::CaptureStack)
+        vm.interpreter-&gt;getStackTrace(stackTrace);
</ins><span class="cx">     m_stack = RefCountedArray&lt;StackFrame&gt;(stackTrace);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExceptionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Exception.h (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Exception.h        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/runtime/Exception.h        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -36,7 +36,11 @@
</span><span class="cx">     typedef JSNonFinalObject Base;
</span><span class="cx">     static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
</span><span class="cx"> 
</span><del>-    static Exception* create(VM&amp;, JSValue thrownValue);
</del><ins>+    enum StackCaptureAction {
+        CaptureStack,
+        DoNotCaptureStack
+    };
+    JS_EXPORT_PRIVATE static Exception* create(VM&amp;, JSValue thrownValue, StackCaptureAction = CaptureStack);
</ins><span class="cx"> 
</span><span class="cx">     static const bool needsDestruction = true;
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="lines">@@ -52,11 +56,6 @@
</span><span class="cx">         return OBJECT_OFFSETOF(Exception, m_value);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static Exception* cast(JSValue exceptionAsJSValue)
-    {
-        return jsCast&lt;Exception*&gt;(exceptionAsJSValue.asCell());
-    }
-
</del><span class="cx">     JSValue value() const { return m_value.get(); }
</span><span class="cx">     const RefCountedArray&lt;StackFrame&gt;&amp; stack() const { return m_stack; }
</span><span class="cx"> 
</span><span class="lines">@@ -67,7 +66,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     Exception(VM&amp;);
</span><del>-    void finishCreation(VM&amp;, JSValue thrownValue);
</del><ins>+    void finishCreation(VM&amp;, JSValue thrownValue, StackCaptureAction);
</ins><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;Unknown&gt; m_value;
</span><span class="cx">     RefCountedArray&lt;StackFrame&gt; m_stack;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -374,11 +374,20 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void clearException() { m_exception = nullptr; }
</span><del>-    void setException(Exception* exception) { m_exception = exception; }
</del><ins>+    void clearLastException() { m_lastException = nullptr; }
</ins><span class="cx"> 
</span><ins>+    void setException(Exception* exception)
+    {
+        m_exception = exception;
+        m_lastException = exception;
+    }
+
</ins><span class="cx">     Exception* exception() const { return m_exception; }
</span><span class="cx">     JSCell** addressOfException() { return reinterpret_cast&lt;JSCell**&gt;(&amp;m_exception); }
</span><span class="cx"> 
</span><ins>+    Exception* lastException() const { return m_lastException; }
+    JSCell** addressOfLastException() { return reinterpret_cast&lt;JSCell**&gt;(&amp;m_lastException); }
+
</ins><span class="cx">     JS_EXPORT_PRIVATE void throwException(ExecState*, Exception*);
</span><span class="cx">     JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
</span><span class="cx">     JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
</span><span class="lines">@@ -570,6 +579,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     void* m_lastStackTop;
</span><span class="cx">     Exception* m_exception { nullptr };
</span><ins>+    Exception* m_lastException { nullptr };
</ins><span class="cx">     bool m_inDefineOwnProperty;
</span><span class="cx">     std::unique_ptr&lt;CodeCache&gt; m_codeCache;
</span><span class="cx">     LegacyProfiler* m_enabledProfiler;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMEntryScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VMEntryScope.cpp (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VMEntryScope.cpp        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/JavaScriptCore/runtime/VMEntryScope.cpp        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx">         // observe time xone changes.
</span><span class="cx">         vm.resetDateCache();
</span><span class="cx">     }
</span><ins>+
+    vm.clearLastException();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void VMEntryScope::setEntryScopeDidPopListener(void* key, EntryScopeDidPopListener listener)
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebCore/ChangeLog        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2015-06-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        API test added: WebKit1.ReportExceptionTest.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::reportException):
+        - Added a version of reportException() that takes a JSValue instead of an Exception
+          object.  This version will ensure that we have an Exception object before calling
+          into the original reportException() as follows:
+
+          1. If the JSValue is already an Exception object, we're good to go.
+
+          2. Else, if VM::lastException() is available, use that as the exception.
+             This is how the old code use to behave (in terms of where it gets the exception
+             stack trace).  The assumption is that reportException() will be called in
+             a timely manner before the exception stack trace has been purged.
+
+          3. Else, create an Exception object with no stack trace.  This is the fall back
+             in case the client did not call reportException() in a timely manner.
+
+        - Also clear the last exception after we've reported it.  This is how the old code
+          before r185259 behave (in terms of the lifecycle of the last exception stack
+          trace).  We're restoring that behavior here.
+
+        * bindings/js/JSDOMBinding.h:
+
</ins><span class="cx"> 2015-06-11  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Do not crash when the descendant frame tree is destroyed during layout.
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -139,6 +139,19 @@
</span><span class="cx">     return JSC::constructArray(exec, 0, globalObject, list);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void reportException(ExecState* exec, JSValue exceptionValue, CachedScript* cachedScript)
+{
+    RELEASE_ASSERT(exec-&gt;vm().currentThreadIsHoldingAPILock());
+    Exception* exception = jsDynamicCast&lt;Exception*&gt;(exceptionValue);
+    if (!exception) {
+        exception = exec-&gt;lastException();
+        if (!exception)
+            exception = Exception::create(exec-&gt;vm(), exceptionValue, Exception::DoNotCaptureStack);
+    }
+
+    reportException(exec, exception, cachedScript);
+}
+
</ins><span class="cx"> void reportException(ExecState* exec, Exception* exception, CachedScript* cachedScript)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(exec-&gt;vm().currentThreadIsHoldingAPILock());
</span><span class="lines">@@ -149,6 +162,7 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;ScriptCallStack&gt; callStack(createScriptCallStackFromException(exec, exception, ScriptCallStack::maxCallStackSizeToCapture));
</span><span class="cx">     exec-&gt;clearException();
</span><ins>+    exec-&gt;clearLastException();
</ins><span class="cx"> 
</span><span class="cx">     JSDOMGlobalObject* globalObject = jsCast&lt;JSDOMGlobalObject*&gt;(exec-&gt;lexicalGlobalObject());
</span><span class="cx">     if (JSDOMWindow* window = jsDynamicCast&lt;JSDOMWindow*&gt;(globalObject)) {
</span><span class="lines">@@ -172,7 +186,11 @@
</span><span class="cx">         // FIXME: &lt;http://webkit.org/b/115087&gt; Web Inspector: WebCore::reportException should not evaluate JavaScript handling exceptions
</span><span class="cx">         // If this is a custon exception object, call toString on it to try and get a nice string representation for the exception.
</span><span class="cx">         errorMessage = exception-&gt;value().toString(exec)-&gt;value(exec);
</span><ins>+
+        // We need to clear any new exception that may be thrown in the toString() call above.
+        // reportException() is not supposed to be making new exceptions.
</ins><span class="cx">         exec-&gt;clearException();
</span><ins>+        exec-&gt;clearLastException();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ScriptExecutionContext* scriptExecutionContext = globalObject-&gt;scriptExecutionContext();
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -242,6 +242,7 @@
</span><span class="cx"> 
</span><span class="cx"> const JSC::HashTable&amp; getHashTableForGlobalData(JSC::VM&amp;, const JSC::HashTable&amp; staticTable);
</span><span class="cx"> 
</span><ins>+WEBCORE_EXPORT void reportException(JSC::ExecState*, JSC::JSValue exception, CachedScript* = nullptr);
</ins><span class="cx"> WEBCORE_EXPORT void reportException(JSC::ExecState*, JSC::Exception*, CachedScript* = nullptr);
</span><span class="cx"> void reportCurrentException(JSC::ExecState*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebKit/mac/ChangeLog        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-06-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        * WebView/WebView.mm:
+        (+[WebView _reportException:inContext:]):
+        - Don't assume we have an Exception object.  Let WebCore::reportException() take
+          care of it.
+
</ins><span class="cx"> 2015-06-11  Jon Lee  &lt;jonlee@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update media controls JS and CSS to use picture-in-picture
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebViewWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebView/WebView.mm (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebView/WebView.mm        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebKit/mac/WebView/WebView.mm        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -722,8 +722,7 @@
</span><span class="cx">     if (!toJSDOMWindow(execState-&gt;lexicalGlobalObject()))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    Exception* vmException = Exception::cast(toJS(execState, exception));
-    reportException(execState, vmException);
</del><ins>+    reportException(execState, toJS(execState, exception));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void WebKitInitializeApplicationCachePathIfNecessary()
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebKit/win/ChangeLog        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-06-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        * WebView.cpp:
+        (WebView::reportException):
+        - Don't assume we have an Exception object.  Let WebCore::reportException() take
+          care of it.
+
</ins><span class="cx"> 2015-06-09  Hyungwook Lee  &lt;hyungwook.lee@navercorp.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Implement dumpProgressFinishedCallback() for Win layoutTestController.
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebView.cpp (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebView.cpp        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebKit/win/WebView.cpp        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -6046,8 +6046,7 @@
</span><span class="cx">     if (!toJSDOMWindow(execState-&gt;lexicalGlobalObject()))
</span><span class="cx">         return E_FAIL;
</span><span class="cx"> 
</span><del>-    JSC::Exception* vmException = JSC::Exception::cast(toJS(execState, exception));
-    WebCore::reportException(execState, vmException);
</del><ins>+    WebCore::reportException(execState, toJS(execState, exception));
</ins><span class="cx">     return S_OK;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebKit2/ChangeLog        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-06-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        * WebProcess/InjectedBundle/InjectedBundle.cpp:
+        (WebKit::InjectedBundle::reportException):
+        - Don't assume we have an Exception object.  Let WebCore::reportException() take
+          care of it.
+
</ins><span class="cx"> 2015-06-11  Carlos Alberto Lopez Perez  &lt;clopez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CMake] Unreviewed build fix after r185479.
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessInjectedBundleInjectedBundlecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -523,7 +523,7 @@
</span><span class="cx">     if (!toJSDOMWindow(execState-&gt;lexicalGlobalObject()))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    WebCore::reportException(execState, Exception::cast(toJS(execState, exception)));
</del><ins>+    WebCore::reportException(execState, toJS(execState, exception));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InjectedBundle::didCreatePage(WebPage* page)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Tools/ChangeLog        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-06-11  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        * TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm:
+        (-[DidCreateJavaScriptContextFrameLoadDelegate webView:didCreateJavaScriptContext:forFrame:]):
+        - Exercises the JSC ObjC API to call a function which throws an exception.  That
+          exception will be returned as a JSValue instead of an Exception object.  We
+          will use this JSValue to test WebCore::reportException() to confirm that it is
+          able to handle an exception value which is not an Exception object.
+
</ins><span class="cx"> 2015-06-11  Dewei Zhu  &lt;dewei_zhu@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move cursor to corner and fix safari window size before running benchmark
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsmacWebViewDidCreateJavaScriptContextmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm (185486 => 185487)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm        2015-06-12 04:09:11 UTC (rev 185486)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm        2015-06-12 05:39:28 UTC (rev 185487)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #import &lt;JavaScriptCore/JSExport.h&gt;
</span><span class="cx"> #import &lt;JavaScriptCore/JSContext.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebFrameLoadDelegatePrivate.h&gt;
</span><ins>+#import &lt;WebKit/WebViewPrivate.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if JSC_OBJC_API_ENABLED
</span><span class="lines">@@ -39,6 +40,7 @@
</span><span class="cx"> static bool didCallWindowCallback = false;
</span><span class="cx"> static bool didFindMyCustomProperty = false;
</span><span class="cx"> static bool didInsertMyCustomProperty = true;
</span><ins>+static bool didReportException = false;
</ins><span class="cx"> 
</span><span class="cx"> @protocol MyConsole&lt;JSExport&gt;
</span><span class="cx"> - (void)log:(NSString *)s;
</span><span class="lines">@@ -107,6 +109,27 @@
</span><span class="cx">         [element setValue:fortyTwo forProperty:@&quot;myCustomProperty&quot;];
</span><span class="cx">         didInsertMyCustomProperty = true;
</span><span class="cx">     };
</span><ins>+
+    context[@&quot;testReportException&quot;] = ^{
+        JSContext* context = [JSContext currentContext];
+        [context evaluateScript:@&quot;function doThrow() { throw 'TestError'; }&quot;];
+
+        JSGlobalContextRef globalContext = [context JSGlobalContextRef];
+        JSObjectRef globalObject = JSContextGetGlobalObject(globalContext);
+
+        JSStringRef jsString = JSStringCreateWithUTF8CString(&quot;doThrow&quot;);
+        JSValueRef function = JSObjectGetProperty(globalContext, globalObject, jsString, nullptr);
+        JSStringRelease(jsString);
+
+        const JSValueRef arguments[] = { };
+
+        JSValueRef exception = 0;
+        JSObjectCallAsFunction(globalContext, (JSObjectRef)function, globalObject, 0, arguments, &amp;exception);
+        if (exception) {
+            [WebView _reportException:exception inContext:globalContext];
+            didReportException = true;
+        }
+    };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @end
</span><span class="lines">@@ -283,6 +306,29 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WebKit1, ReportExceptionTest)
+{
+    didReportException = false;
+    @autoreleasepool {
+        RetainPtr&lt;WebView&gt; webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+        RetainPtr&lt;DidCreateJavaScriptContextFrameLoadDelegate&gt; frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]);
+        
+        webView.get().frameLoadDelegate = frameLoadDelegate.get();
+        WebFrame *mainFrame = webView.get().mainFrame;
+        
+        NSString *bodyString =
+            @&quot;&lt;body&gt; \
+                &lt;script&gt; \
+                    testReportException(); \
+                &lt;/script&gt; \
+            &lt;/body&gt;&quot;;
+        NSURL *aboutBlankURL = [NSURL URLWithString:@&quot;about:blank&quot;];
+        
+        [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL];
+        Util::run(&amp;didReportException);
+    }
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JSC_OBJC_API)
</span></span></pre>
</div>
</div>

</body>
</html>