Use NakedPtr<Exception>& to return exception results.
https://bugs.webkit.org/show_bug.cgi?id=145870
Reviewed by Anders Carlsson and Filip Pizlo.
Source/JavaScriptCore:
Before r185259, calls into the VM takes a JSValue* exception result argument for
returning any uncaught exception that may have been thrown while executing JS code.
As a result, clients of the VM functions will declare a local JSValue exception
result which is automatically initialized to a null value (i.e. the empty value,
not the JS null value).
With r185259, the VM functions were changed to take an Exception*& exception result
instead, and the VM functions are responsible for initializing the exception result
to null if no exception is thrown.
This introduces 2 issues:
- the VM functions are vulnerable to modifications that may add early returns
before the exception result is nullified. This can result in the exception
result being used without initialization.
- Previously, a client could technically use the same exception result for more
than one calls into the VM functions. If an earlier call sets it to a thrown
value, the thrown value will stick unless a subsequent call throws a different
exception.
With the new Exception*& exception result, the VM functions will always clear
the exception result before proceeding. As a result, the client's exception
result will be null after the second call even though the first call saw an
exception thrown. This is a change in the expected behavior.
To fix these issues, we'll introduce a NakedPtr smart pointer whose sole purpose
is to guarantee that the pointer is initialized. The VM functions will now take
a NakedPtr<Exception>& instead of the Exception*&. This ensures that the
exception result is initialized.
The VM functions be also reverted to only set the exception result if a new
exception is thrown.
(JSEvaluateScript):
- API/JSScriptRef.cpp:
- bindings/ScriptFunctionCall.cpp:
(Deprecated::ScriptFunctionCall::call):
- bindings/ScriptFunctionCall.h:
- debugger/Debugger.cpp:
(JSC::Debugger::hasBreakpoint):
- debugger/Debugger.h:
- debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::thisValue):
(JSC::DebuggerCallFrame::evaluate):
- debugger/DebuggerCallFrame.h:
(JSC::DebuggerCallFrame::isValid):
- inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::createInjectedScript):
- inspector/InspectorEnvironment.h:
- inspector/JSJavaScriptCallFrame.cpp:
(Inspector::JSJavaScriptCallFrame::evaluate):
- inspector/JavaScriptCallFrame.h:
(Inspector::JavaScriptCallFrame::vmEntryGlobalObject):
(Inspector::JavaScriptCallFrame::thisValue):
(Inspector::JavaScriptCallFrame::evaluate):
- inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::evaluateBreakpointAction):
(functionRun):
(functionLoad):
(runWithScripts):
(runInteractive):
(JSC::call):
- runtime/CallData.h:
- runtime/Completion.cpp:
(JSC::checkSyntax):
(JSC::evaluate):
(JSC::evaluate):
Source/WebCore:
No new WebCore tests because this functionality is already covered by existing tests.
API tests added for WTF::NakedPtr.
- bindings/js/JSCallbackData.cpp:
(WebCore::JSCallbackData::invokeCallback):
- bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
- bindings/js/JSErrorHandler.cpp:
(WebCore::JSErrorHandler::handleEvent):
- bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
- bindings/js/JSMainThreadExecState.cpp:
(WebCore::JSMainThreadExecState::didLeaveScriptContext):
(WebCore::functionCallHandlerFromAnyThread):
(WebCore::evaluateHandlerFromAnyThread):
- bindings/js/JSMainThreadExecState.h:
(WebCore::JSMainThreadExecState::currentState):
(WebCore::JSMainThreadExecState::call):
(WebCore::JSMainThreadExecState::evaluate):
- bindings/js/JSMutationCallback.cpp:
(WebCore::JSMutationCallback::call):
- bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::executeFunctionInContext):
- bindings/js/ScriptController.cpp:
(WebCore::ScriptController::evaluateInWorld):
- bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::evaluate):
(WebCore::WorkerScriptController::setException):
- bindings/js/WorkerScriptController.h:
(WebCore::WorkerScriptController::workerGlobalScopeWrapper):
- bindings/objc/WebScriptObject.mm:
(-[WebScriptObject callWebScriptMethod:withArguments:]):
- workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::importScripts):
Source/WTF:
Introducing the NakedPtr class.
- WTF.xcodeproj/project.pbxproj:
- wtf/NakedPtr.h: Added.
(WTF::NakedPtr::NakedPtr):
(WTF::NakedPtr::get):
(WTF::NakedPtr::clear):
(WTF::NakedPtr::operator*):
(WTF::NakedPtr::operator->):
(WTF::NakedPtr::operator T*):
(WTF::NakedPtr::operator!):
(WTF::NakedPtr::operator bool):
(WTF::=):
(WTF::NakedPtr<T>::swap):
(WTF::swap):
Tools:
- TestWebKitAPI/CMakeLists.txt:
- TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj:
- TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters:
- TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
- TestWebKitAPI/Tests/WTF/NakedPtr.cpp: Added.
(TestWebKitAPI::TEST):
(TestWebKitAPI::nakedPtrFoo):