diff options
Diffstat (limited to 'Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp')
-rw-r--r-- | Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp | 219 |
1 files changed, 58 insertions, 161 deletions
diff --git a/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index 7ea887833..7d584d74c 100644 --- a/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -39,13 +39,13 @@ #include "HTMLDocument.h" #include "InspectorInstrumentation.h" #include "JSBlob.h" +#include "JSDOMConvert.h" #include "JSDOMFormData.h" #include "JSDOMWindowCustom.h" #include "JSDocument.h" #include "JSEvent.h" #include "JSEventListener.h" #include "XMLHttpRequest.h" -#include <interpreter/StackVisitor.h> #include <runtime/ArrayBuffer.h> #include <runtime/Error.h> #include <runtime/JSArrayBuffer.h> @@ -56,184 +56,81 @@ using namespace JSC; namespace WebCore { -void JSXMLHttpRequest::visitChildren(JSCell* cell, SlotVisitor& visitor) +void JSXMLHttpRequest::visitAdditionalChildren(SlotVisitor& visitor) { - JSXMLHttpRequest* thisObject = jsCast<JSXMLHttpRequest*>(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, info()); - COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); - Base::visitChildren(thisObject, visitor); - - if (XMLHttpRequestUpload* upload = thisObject->m_impl->optionalUpload()) + if (XMLHttpRequestUpload* upload = wrapped().optionalUpload()) visitor.addOpaqueRoot(upload); - if (Document* responseDocument = thisObject->m_impl->optionalResponseXML()) + if (Document* responseDocument = wrapped().optionalResponseXML()) visitor.addOpaqueRoot(responseDocument); - - if (ArrayBuffer* responseArrayBuffer = thisObject->m_impl->optionalResponseArrayBuffer()) - visitor.addOpaqueRoot(responseArrayBuffer); - - if (Blob* responseBlob = thisObject->m_impl->optionalResponseBlob()) - visitor.addOpaqueRoot(responseBlob); - - if (thisObject->m_response) - visitor.append(&thisObject->m_response); - - thisObject->m_impl->visitJSEventListeners(visitor); } -// Custom functions -JSValue JSXMLHttpRequest::open(ExecState* exec) +JSValue JSXMLHttpRequest::responseText(ExecState& state) const { - if (exec->argumentCount() < 2) - return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); - - const URL& url = impl().scriptExecutionContext()->completeURL(exec->uncheckedArgument(1).toString(exec)->value(exec)); - String method = exec->uncheckedArgument(0).toString(exec)->value(exec); - - ExceptionCode ec = 0; - if (exec->argumentCount() >= 3) { - bool async = exec->uncheckedArgument(2).toBoolean(exec); - if (!exec->argument(3).isUndefined()) { - String user = valueToStringWithNullCheck(exec, exec->uncheckedArgument(3)); - - if (!exec->argument(4).isUndefined()) { - String password = valueToStringWithNullCheck(exec, exec->uncheckedArgument(4)); - impl().open(method, url, async, user, password, ec); - } else - impl().open(method, url, async, user, ec); - } else - impl().open(method, url, async, ec); - } else - impl().open(method, url, ec); - - setDOMException(exec, ec); - return jsUndefined(); -} - -class SendFunctor { -public: - SendFunctor() - : m_hasSkippedFirstFrame(false) - , m_line(0) - , m_column(0) - { - } + auto result = wrapped().responseText(); - unsigned line() const { return m_line; } - unsigned column() const { return m_column; } - String url() const { return m_url; } - - StackVisitor::Status operator()(StackVisitor& visitor) - { - if (!m_hasSkippedFirstFrame) { - m_hasSkippedFirstFrame = true; - return StackVisitor::Continue; - } - - unsigned line = 0; - unsigned column = 0; - visitor->computeLineAndColumn(line, column); - m_line = line; - m_column = column; - m_url = visitor->sourceURL(); - return StackVisitor::Done; + if (UNLIKELY(result.hasException())) { + auto& vm = state.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + propagateException(state, scope, result.releaseException()); + return { }; } -private: - bool m_hasSkippedFirstFrame; - unsigned m_line; - unsigned m_column; - String m_url; -}; + auto resultValue = result.releaseReturnValue(); + if (resultValue.isNull()) + return jsNull(); -JSValue JSXMLHttpRequest::send(ExecState* exec) -{ - InspectorInstrumentation::willSendXMLHttpRequest(impl().scriptExecutionContext(), impl().url()); - - ExceptionCode ec = 0; - JSValue val = exec->argument(0); - if (val.isUndefinedOrNull()) - impl().send(ec); - else if (val.inherits(JSDocument::info())) - impl().send(toDocument(val), ec); - else if (val.inherits(JSBlob::info())) - impl().send(toBlob(val), ec); - else if (val.inherits(JSDOMFormData::info())) - impl().send(toDOMFormData(val), ec); - else if (val.inherits(JSArrayBuffer::info())) - impl().send(toArrayBuffer(val), ec); - else if (val.inherits(JSArrayBufferView::info())) { - RefPtr<ArrayBufferView> view = toArrayBufferView(val); - impl().send(view.get(), ec); - } else - impl().send(val.toString(exec)->value(exec), ec); - - SendFunctor functor; - exec->iterate(functor); - impl().setLastSendLineAndColumnNumber(functor.line(), functor.column()); - impl().setLastSendURL(functor.url()); - setDOMException(exec, ec); - return jsUndefined(); + // See JavaScriptCore for explanation: Should be used for any string that is already owned by another + // object, to let the engine know that collecting the JSString wrapper is unlikely to save memory. + return jsOwnedString(&state, resultValue); } -JSValue JSXMLHttpRequest::responseText(ExecState* exec) const +JSValue JSXMLHttpRequest::retrieveResponse(ExecState& state) { - ExceptionCode ec = 0; - String text = impl().responseText(ec); - if (ec) { - setDOMException(exec, ec); + auto type = wrapped().responseType(); + + switch (type) { + case XMLHttpRequest::ResponseType::EmptyString: + case XMLHttpRequest::ResponseType::Text: + return responseText(state); + default: + break; + } + + if (!wrapped().doneWithoutErrors()) + return jsNull(); + + JSValue value; + switch (type) { + case XMLHttpRequest::ResponseType::EmptyString: + case XMLHttpRequest::ResponseType::Text: + ASSERT_NOT_REACHED(); return jsUndefined(); + + case XMLHttpRequest::ResponseType::Json: + value = JSONParse(&state, wrapped().responseTextIgnoringResponseType()); + if (!value) + value = jsNull(); + break; + + case XMLHttpRequest::ResponseType::Document: { + auto document = wrapped().responseXML(); + ASSERT(!document.hasException()); + value = toJS<IDLInterface<Document>>(state, *globalObject(), document.releaseReturnValue()); + break; } - return jsOwnedStringOrNull(exec, text); -} -JSValue JSXMLHttpRequest::response(ExecState* exec) const -{ - switch (impl().responseTypeCode()) { - case XMLHttpRequest::ResponseTypeDefault: - case XMLHttpRequest::ResponseTypeText: - return responseText(exec); - - case XMLHttpRequest::ResponseTypeJSON: - { - // FIXME: Use CachedAttribute for other types as well. - if (m_response && impl().responseCacheIsValid()) - return m_response.get(); - - if (!impl().doneWithoutErrors()) - return jsNull(); - - JSValue value = JSONParse(exec, impl().responseTextIgnoringResponseType()); - if (!value) - value = jsNull(); - JSXMLHttpRequest* jsRequest = const_cast<JSXMLHttpRequest*>(this); - jsRequest->m_response.set(exec->vm(), jsRequest, value); - - impl().didCacheResponseJSON(); - - return value; - } - - case XMLHttpRequest::ResponseTypeDocument: - { - ExceptionCode ec = 0; - Document* document = impl().responseXML(ec); - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - return toJS(exec, globalObject(), document); - } - - case XMLHttpRequest::ResponseTypeBlob: - return toJS(exec, globalObject(), impl().responseBlob()); - - case XMLHttpRequest::ResponseTypeArrayBuffer: - return toJS(exec, globalObject(), impl().responseArrayBuffer()); + case XMLHttpRequest::ResponseType::Blob: + value = toJSNewlyCreated<IDLInterface<Blob>>(state, *globalObject(), wrapped().createResponseBlob()); + break; + + case XMLHttpRequest::ResponseType::Arraybuffer: + value = toJS<IDLInterface<ArrayBuffer>>(state, *globalObject(), wrapped().createResponseArrayBuffer()); + break; } - return jsUndefined(); + wrapped().didCacheResponse(); + return value; } } // namespace WebCore |