diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/domjit | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/domjit')
-rw-r--r-- | Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml | 12 | ||||
-rw-r--r-- | Source/WebCore/domjit/DOMJITCheckDOM.h | 96 | ||||
-rw-r--r-- | Source/WebCore/domjit/DOMJITHelpers.cpp | 55 | ||||
-rw-r--r-- | Source/WebCore/domjit/DOMJITHelpers.h | 190 | ||||
-rw-r--r-- | Source/WebCore/domjit/DOMJITIDLConvert.h | 49 | ||||
-rw-r--r-- | Source/WebCore/domjit/DOMJITIDLType.h | 47 | ||||
-rw-r--r-- | Source/WebCore/domjit/DOMJITIDLTypeFilter.h | 71 | ||||
-rw-r--r-- | Source/WebCore/domjit/JSDocumentDOMJIT.cpp | 151 | ||||
-rw-r--r-- | Source/WebCore/domjit/JSNodeDOMJIT.cpp | 199 | ||||
-rw-r--r-- | Source/WebCore/domjit/generate-abstract-heap.rb | 165 |
10 files changed, 1035 insertions, 0 deletions
diff --git a/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml b/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml new file mode 100644 index 000000000..1b156ee1b --- /dev/null +++ b/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml @@ -0,0 +1,12 @@ +DOM: + Tree: + Node: + - Node_firstChild + - Node_lastChild + - Node_parentNode + - Node_nextSibling + - Node_previousSibling + - Node_ownerDocument + Document: + - Document_documentElement + - Document_body diff --git a/Source/WebCore/domjit/DOMJITCheckDOM.h b/Source/WebCore/domjit/DOMJITCheckDOM.h new file mode 100644 index 000000000..1ba310631 --- /dev/null +++ b/Source/WebCore/domjit/DOMJITCheckDOM.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#pragma once + +#include "DOMJITHelpers.h" + +#if ENABLE(JIT) + +#include "Document.h" +#include "Element.h" +#include "Event.h" +#include "Node.h" + +namespace WebCore { namespace DOMJIT { + +template<typename DOMInterface> +struct TypeChecker { +}; + +template<> +struct TypeChecker<Node> { + static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom) + { + return DOMJIT::branchIfNotNode(jit, dom); + } +}; + +template<> +struct TypeChecker<Document> { + static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom) + { + return DOMJIT::branchIfNotDocumentWrapper(jit, dom); + } +}; + +template<> +struct TypeChecker<DocumentFragment> { + static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom) + { + return DOMJIT::branchIfNotDocumentFragment(jit, dom); + } +}; + +template<> +struct TypeChecker<Event> { + static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom) + { + return DOMJIT::branchIfNotEvent(jit, dom); + } +}; + +template<> +struct TypeChecker<Element> { + static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom) + { + return DOMJIT::branchIfNotElement(jit, dom); + } +}; + +template<typename DOMInterface> +Ref<JSC::DOMJIT::Patchpoint> checkDOM() +{ + Ref<JSC::DOMJIT::Patchpoint> patchpoint = JSC::DOMJIT::Patchpoint::create(); + patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { + return TypeChecker<DOMInterface>::branchIfFail(jit, params[0].gpr()); + }); + return patchpoint; +} + +} } + +#endif diff --git a/Source/WebCore/domjit/DOMJITHelpers.cpp b/Source/WebCore/domjit/DOMJITHelpers.cpp new file mode 100644 index 000000000..d48fca052 --- /dev/null +++ b/Source/WebCore/domjit/DOMJITHelpers.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DOMJITHelpers.h" + +#if ENABLE(JIT) + +#include "Document.h" +#include "JSDOMBinding.h" +#include "Node.h" + +namespace WebCore { namespace DOMJIT { + +using JSC::CCallHelpers; +using JSC::GPRReg; +using JSC::JSValueRegs; +using JSC::MacroAssembler; + +void loadDocument(MacroAssembler& jit, GPRReg node, GPRReg output) +{ + jit.loadPtr(CCallHelpers::Address(node, Node::treeScopeMemoryOffset()), output); + jit.loadPtr(CCallHelpers::Address(output, TreeScope::documentScopeMemoryOffset()), output); +} + +void loadDocumentElement(MacroAssembler& jit, GPRReg document, GPRReg output) +{ + jit.loadPtr(CCallHelpers::Address(document, Document::documentElementMemoryOffset()), output); +} + +} } + +#endif diff --git a/Source/WebCore/domjit/DOMJITHelpers.h b/Source/WebCore/domjit/DOMJITHelpers.h new file mode 100644 index 000000000..1370e5629 --- /dev/null +++ b/Source/WebCore/domjit/DOMJITHelpers.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2016 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#pragma once + +#include "JSDOMWrapper.h" +#include "Node.h" +#include <domjit/DOMJITPatchpoint.h> +#include <domjit/DOMJITPatchpointParams.h> +#include <interpreter/FrameTracers.h> + +#if ENABLE(JIT) + +namespace WebCore { namespace DOMJIT { + +using JSC::CCallHelpers; +using JSC::GPRReg; +using JSC::JSValueRegs; +using JSC::MacroAssembler; + +static_assert(std::is_same<GPRReg, MacroAssembler::RegisterID>::value, "GPRReg is the alias to the MacroAssembler::RegisterID"); + +inline CCallHelpers::Jump branchIfNotWorldIsNormal(CCallHelpers& jit, GPRReg globalObject) +{ + return jit.branchTest8(CCallHelpers::Zero, CCallHelpers::Address(globalObject, JSDOMGlobalObject::offsetOfWorldIsNormal())); +} + +inline CCallHelpers::Jump branchIfNotWeakIsLive(CCallHelpers& jit, GPRReg weakImpl) +{ + return jit.branchTestPtr(CCallHelpers::NonZero, CCallHelpers::Address(weakImpl, JSC::WeakImpl::offsetOfWeakHandleOwner()), CCallHelpers::TrustedImm32(JSC::WeakImpl::StateMask)); +} + +template<typename WrappedNode> +JSC::EncodedJSValue JIT_OPERATION toWrapperSlow(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject, void* result) +{ + ASSERT(exec); + ASSERT(result); + ASSERT(globalObject); + JSC::NativeCallFrameTracer tracer(&exec->vm(), exec); + return JSC::JSValue::encode(toJS(exec, static_cast<JSDOMGlobalObject*>(globalObject), *static_cast<WrappedNode*>(result))); +} + +template<typename WrappedType> +void tryLookUpWrapperCache(CCallHelpers& jit, CCallHelpers::JumpList& failureCases, GPRReg wrapped, GPRReg resultGPR) +{ + jit.loadPtr(CCallHelpers::Address(wrapped, ScriptWrappable::offsetOfWrapper<WrappedType>()), resultGPR); + failureCases.append(jit.branchTestPtr(CCallHelpers::Zero, resultGPR)); + failureCases.append(branchIfNotWeakIsLive(jit, resultGPR)); + jit.loadPtr(CCallHelpers::Address(resultGPR, JSC::WeakImpl::offsetOfJSValue() + JSC::JSValue::offsetOfPayload()), resultGPR); +} + +template<typename WrappedType, typename ToJSFunction> +void toWrapper(CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params, GPRReg wrapped, GPRReg globalObject, JSValueRegs result, ToJSFunction function, JSC::JSValue globalObjectConstant) +{ + ASSERT(wrapped != result.payloadGPR()); + ASSERT(globalObject != result.payloadGPR()); + GPRReg payloadGPR = result.payloadGPR(); + CCallHelpers::JumpList slowCases; + + if (globalObjectConstant) { + if (!JSC::jsCast<JSDOMGlobalObject*>(globalObjectConstant)->worldIsNormal()) { + slowCases.append(jit.jump()); + params.addSlowPathCall(slowCases, jit, function, result, globalObject, wrapped); + return; + } + } else + slowCases.append(branchIfNotWorldIsNormal(jit, globalObject)); + + tryLookUpWrapperCache<WrappedType>(jit, slowCases, wrapped, payloadGPR); + jit.boxCell(payloadGPR, result); + params.addSlowPathCall(slowCases, jit, function, result, globalObject, wrapped); +} + +inline CCallHelpers::Jump branchIfDOMWrapper(CCallHelpers& jit, GPRReg target) +{ + return jit.branch8( + CCallHelpers::AboveOrEqual, + CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()), + CCallHelpers::TrustedImm32(JSC::JSType(JSDOMWrapperType))); +} + +inline CCallHelpers::Jump branchIfNotDOMWrapper(CCallHelpers& jit, GPRReg target) +{ + return jit.branch8( + CCallHelpers::Below, + CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()), + CCallHelpers::TrustedImm32(JSC::JSType(JSDOMWrapperType))); +} + +inline CCallHelpers::Jump branchIfEvent(CCallHelpers& jit, GPRReg target) +{ + return jit.branchIfType(target, JSC::JSType(JSEventType)); +} + +inline CCallHelpers::Jump branchIfNotEvent(CCallHelpers& jit, GPRReg target) +{ + return jit.branchIfNotType(target, JSC::JSType(JSEventType)); +} + +inline CCallHelpers::Jump branchIfNode(CCallHelpers& jit, GPRReg target) +{ + return jit.branch8( + CCallHelpers::AboveOrEqual, + CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()), + CCallHelpers::TrustedImm32(JSC::JSType(JSNodeType))); +} + +inline CCallHelpers::Jump branchIfNotNode(CCallHelpers& jit, GPRReg target) +{ + return jit.branch8( + CCallHelpers::Below, + CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()), + CCallHelpers::TrustedImm32(JSC::JSType(JSNodeType))); +} + +inline CCallHelpers::Jump branchIfElement(CCallHelpers& jit, GPRReg target) +{ + return jit.branch8( + CCallHelpers::AboveOrEqual, + CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()), + CCallHelpers::TrustedImm32(JSC::JSType(JSElementType))); +} + +inline CCallHelpers::Jump branchIfNotElement(CCallHelpers& jit, GPRReg target) +{ + return jit.branch8( + CCallHelpers::Below, + CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()), + CCallHelpers::TrustedImm32(JSC::JSType(JSElementType))); +} + +inline CCallHelpers::Jump branchIfDocumentFragment(CCallHelpers& jit, GPRReg target) +{ + return jit.branchIfType(target, JSC::JSType(JSDocumentFragmentNodeType)); +} + +inline CCallHelpers::Jump branchIfNotDocumentFragment(CCallHelpers& jit, GPRReg target) +{ + return jit.branchIfNotType(target, JSC::JSType(JSDocumentFragmentNodeType)); +} + +inline CCallHelpers::Jump branchIfDocumentWrapper(CCallHelpers& jit, GPRReg target) +{ + return jit.branchIfType(target, JSC::JSType(JSDocumentWrapperType)); +} + +inline CCallHelpers::Jump branchIfNotDocumentWrapper(CCallHelpers& jit, GPRReg target) +{ + return jit.branchIfNotType(target, JSC::JSType(JSDocumentWrapperType)); +} + +void loadDocument(MacroAssembler&, GPRReg node, GPRReg output); +void loadDocumentElement(MacroAssembler&, GPRReg document, GPRReg output); + +inline CCallHelpers::Jump branchTestIsElementFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress) +{ + return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsElement())); +} + +inline CCallHelpers::Jump branchTestIsHTMLFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress) +{ + return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsHTML())); +} + +} } + +#endif diff --git a/Source/WebCore/domjit/DOMJITIDLConvert.h b/Source/WebCore/domjit/DOMJITIDLConvert.h new file mode 100644 index 000000000..5e00abfcc --- /dev/null +++ b/Source/WebCore/domjit/DOMJITIDLConvert.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "IDLTypes.h" +#include <bytecode/SpeculatedType.h> +#include <domjit/DOMJITSignature.h> + +namespace WebCore { namespace DOMJIT { + +template<typename IDLType> +struct DirectConverter; + +template<> +struct DirectConverter<IDLDOMString> { + template<StringConversionConfiguration> + static String directConvert(JSC::ExecState&, JSC::JSString*); +}; + +template<> +inline String DirectConverter<IDLDOMString>::directConvert<StringConversionConfiguration::Normal>(JSC::ExecState& state, JSC::JSString* string) +{ + return string->value(&state); +} + +} } diff --git a/Source/WebCore/domjit/DOMJITIDLType.h b/Source/WebCore/domjit/DOMJITIDLType.h new file mode 100644 index 000000000..6891fbc50 --- /dev/null +++ b/Source/WebCore/domjit/DOMJITIDLType.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "IDLTypes.h" +#include <bytecode/SpeculatedType.h> + +namespace WebCore { namespace DOMJIT { + +template<typename IDLType> +struct IDLJSArgumentTypeSelect; + +template<> struct IDLJSArgumentTypeSelect<IDLBoolean> { typedef bool type; }; +template<> struct IDLJSArgumentTypeSelect<IDLByte> { typedef int32_t type; }; +template<> struct IDLJSArgumentTypeSelect<IDLOctet> { typedef int32_t type; }; +template<> struct IDLJSArgumentTypeSelect<IDLShort> { typedef int32_t type; }; +template<> struct IDLJSArgumentTypeSelect<IDLUnsignedShort> { typedef int32_t type; }; +template<> struct IDLJSArgumentTypeSelect<IDLLong> { typedef int32_t type; }; +template<> struct IDLJSArgumentTypeSelect<IDLDOMString> { typedef JSC::JSString* type; }; + +template<typename IDLType> +using IDLJSArgumentType = typename IDLJSArgumentTypeSelect<IDLType>::type; + +} } diff --git a/Source/WebCore/domjit/DOMJITIDLTypeFilter.h b/Source/WebCore/domjit/DOMJITIDLTypeFilter.h new file mode 100644 index 000000000..d52d99677 --- /dev/null +++ b/Source/WebCore/domjit/DOMJITIDLTypeFilter.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <bytecode/SpeculatedType.h> + +namespace WebCore { namespace DOMJIT { + +template<typename IDLType> +struct IDLArgumentTypeFilter; + +template<> struct IDLArgumentTypeFilter<IDLBoolean> { static const constexpr JSC::SpeculatedType value = JSC::SpecBoolean; }; +template<> struct IDLArgumentTypeFilter<IDLByte> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLArgumentTypeFilter<IDLOctet> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLArgumentTypeFilter<IDLShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLArgumentTypeFilter<IDLUnsignedShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLArgumentTypeFilter<IDLLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLArgumentTypeFilter<IDLDOMString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; }; + +template<typename IDLType> +struct IDLResultTypeFilter { + static const constexpr JSC::SpeculatedType value = JSC::SpecHeapTop; +}; + +template<> struct IDLResultTypeFilter<IDLAny> { static const constexpr JSC::SpeculatedType value = JSC::SpecHeapTop; }; +template<> struct IDLResultTypeFilter<IDLBoolean> { static const constexpr JSC::SpeculatedType value = JSC::SpecBoolean; }; +template<> struct IDLResultTypeFilter<IDLByte> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLResultTypeFilter<IDLOctet> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLResultTypeFilter<IDLShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLResultTypeFilter<IDLUnsignedShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLResultTypeFilter<IDLLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; }; +template<> struct IDLResultTypeFilter<IDLUnsignedLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLLongLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLUnsignedLongLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLFloat> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLUnrestrictedFloat> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLDouble> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLUnrestrictedDouble> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; }; +template<> struct IDLResultTypeFilter<IDLDOMString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; }; +template<> struct IDLResultTypeFilter<IDLByteString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; }; +template<> struct IDLResultTypeFilter<IDLUSVString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; }; + +template<typename T> +struct IDLResultTypeFilter<IDLNullable<T>> { + static const constexpr JSC::SpeculatedType value = JSC::SpecOther | IDLResultTypeFilter<T>::value; +}; + +} } diff --git a/Source/WebCore/domjit/JSDocumentDOMJIT.cpp b/Source/WebCore/domjit/JSDocumentDOMJIT.cpp new file mode 100644 index 000000000..d1a258fb9 --- /dev/null +++ b/Source/WebCore/domjit/JSDocumentDOMJIT.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2016 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSDocument.h" + +#if ENABLE(JIT) + +#include "DOMJITAbstractHeapRepository.h" +#include "DOMJITCheckDOM.h" +#include "DOMJITHelpers.h" +#include "Document.h" +#include "JSDOMWrapper.h" +#include "JSElement.h" +#include "JSHTMLElement.h" +#include <domjit/DOMJITPatchpoint.h> +#include <domjit/DOMJITPatchpointParams.h> + +using namespace JSC; + +namespace WebCore { + +Ref<JSC::DOMJIT::Patchpoint> DocumentDocumentElementDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Document>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentDocumentElementDOMJIT::callDOMGetter() +{ + Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create(); + patchpoint->numGPScratchRegisters = 1; + patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { + JSValueRegs result = params[0].jsValueRegs(); + GPRReg document = params[1].gpr(); + GPRReg globalObject = params[2].gpr(); + JSValue globalObjectValue = params[2].value(); + GPRReg scratch = params.gpScratch(0); + + jit.loadPtr(CCallHelpers::Address(document, JSDocument::offsetOfWrapped()), scratch); + DOMJIT::loadDocumentElement(jit, scratch, scratch); + auto nullCase = jit.branchTestPtr(CCallHelpers::Zero, scratch); + DOMJIT::toWrapper<Element>(jit, params, scratch, globalObject, result, DOMJIT::toWrapperSlow<Element>, globalObjectValue); + auto done = jit.jump(); + + nullCase.link(&jit); + jit.moveValue(jsNull(), result); + done.link(&jit); + + return CCallHelpers::JumpList(); + }); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_documentElement); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> DocumentBodyDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Document>(); +} + +static void loadLocalName(CCallHelpers& jit, GPRReg htmlElement, GPRReg localNameImpl) +{ + jit.loadPtr(CCallHelpers::Address(htmlElement, Element::tagQNameMemoryOffset() + QualifiedName::implMemoryOffset()), localNameImpl); + jit.loadPtr(CCallHelpers::Address(localNameImpl, QualifiedName::QualifiedNameImpl::localNameMemoryOffset()), localNameImpl); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentBodyDOMJIT::callDOMGetter() +{ + Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create(); + patchpoint->numGPScratchRegisters = 2; + patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { + JSValueRegs result = params[0].jsValueRegs(); + GPRReg document = params[1].gpr(); + GPRReg globalObject = params[2].gpr(); + JSValue globalObjectValue = params[2].value(); + GPRReg scratch1 = params.gpScratch(0); + GPRReg scratch2 = params.gpScratch(1); + + jit.loadPtr(CCallHelpers::Address(document, JSDocument::offsetOfWrapped()), scratch1); + DOMJIT::loadDocumentElement(jit, scratch1, scratch1); + + CCallHelpers::JumpList nullCases; + CCallHelpers::JumpList successCases; + nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1)); + nullCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1)); + // We ensured that the name of the given element is HTML qualified. + // It allows us to perform local name comparison! + loadLocalName(jit, scratch1, scratch2); + nullCases.append(jit.branchPtr(CCallHelpers::NotEqual, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::htmlTag.localName().impl()))); + + RELEASE_ASSERT(!CAST_OFFSET(Node*, ContainerNode*)); + RELEASE_ASSERT(!CAST_OFFSET(Node*, Element*)); + RELEASE_ASSERT(!CAST_OFFSET(Node*, HTMLElement*)); + + // Node* node = current.firstChild(); + // while (node && !is<HTMLElement>(*node)) + // node = node->nextSibling(); + // return downcast<HTMLElement>(node); + jit.loadPtr(CCallHelpers::Address(scratch1, ContainerNode::firstChildMemoryOffset()), scratch1); + + CCallHelpers::Label loopStart = jit.label(); + nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1)); + auto notHTMLElementCase = DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1); + // We ensured that the name of the given element is HTML qualified. + // It allows us to perform local name comparison! + loadLocalName(jit, scratch1, scratch2); + successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::bodyTag.localName().impl()))); + successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::framesetTag.localName().impl()))); + + notHTMLElementCase.link(&jit); + jit.loadPtr(CCallHelpers::Address(scratch1, Node::nextSiblingMemoryOffset()), scratch1); + jit.jump().linkTo(loopStart, &jit); + + successCases.link(&jit); + DOMJIT::toWrapper<HTMLElement>(jit, params, scratch1, globalObject, result, DOMJIT::toWrapperSlow<HTMLElement>, globalObjectValue); + auto done = jit.jump(); + + nullCases.link(&jit); + jit.moveValue(jsNull(), result); + done.link(&jit); + + return CCallHelpers::JumpList(); + }); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_body); + return patchpoint; +} + +} + +#endif diff --git a/Source/WebCore/domjit/JSNodeDOMJIT.cpp b/Source/WebCore/domjit/JSNodeDOMJIT.cpp new file mode 100644 index 000000000..29f8b384e --- /dev/null +++ b/Source/WebCore/domjit/JSNodeDOMJIT.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2016 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSNode.h" + +#if ENABLE(JIT) + +#include "DOMJITAbstractHeapRepository.h" +#include "DOMJITCheckDOM.h" +#include "DOMJITHelpers.h" +#include "JSDOMWrapper.h" +#include "Node.h" +#include <domjit/DOMJITPatchpoint.h> +#include <domjit/DOMJITPatchpointParams.h> +#include <interpreter/FrameTracers.h> + +using namespace JSC; + +namespace WebCore { + +enum class IsContainerGuardRequirement { Required, NotRequired }; + +template<typename WrappedNode> +static Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> createCallDOMGetterForOffsetAccess(ptrdiff_t offset, IsContainerGuardRequirement isContainerGuardRequirement) +{ + Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create(); + patchpoint->numGPScratchRegisters = 1; + patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { + JSValueRegs result = params[0].jsValueRegs(); + GPRReg node = params[1].gpr(); + GPRReg globalObject = params[2].gpr(); + GPRReg scratch = params.gpScratch(0); + JSValue globalObjectValue = params[2].value(); + + CCallHelpers::JumpList nullCases; + // Load a wrapped object. "node" should be already type checked by CheckDOM. + jit.loadPtr(CCallHelpers::Address(node, JSNode::offsetOfWrapped()), scratch); + + if (isContainerGuardRequirement == IsContainerGuardRequirement::Required) + nullCases.append(jit.branchTest32(CCallHelpers::Zero, CCallHelpers::Address(scratch, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsContainer()))); + + jit.loadPtr(CCallHelpers::Address(scratch, offset), scratch); + nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch)); + + DOMJIT::toWrapper<WrappedNode>(jit, params, scratch, globalObject, result, DOMJIT::toWrapperSlow<WrappedNode>, globalObjectValue); + CCallHelpers::Jump done = jit.jump(); + + nullCases.link(&jit); + jit.moveValue(jsNull(), result); + done.link(&jit); + return CCallHelpers::JumpList(); + }); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodeFirstChildDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeFirstChildDOMJIT::callDOMGetter() +{ + auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::firstChildMemoryOffset(), IsContainerGuardRequirement::Required); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_firstChild); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodeLastChildDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeLastChildDOMJIT::callDOMGetter() +{ + auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::lastChildMemoryOffset(), IsContainerGuardRequirement::Required); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_lastChild); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodeNextSiblingDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeNextSiblingDOMJIT::callDOMGetter() +{ + auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(Node::nextSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_nextSibling); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodePreviousSiblingDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodePreviousSiblingDOMJIT::callDOMGetter() +{ + auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(Node::previousSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_previousSibling); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodeParentNodeDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeParentNodeDOMJIT::callDOMGetter() +{ + auto patchpoint = createCallDOMGetterForOffsetAccess<ContainerNode>(Node::parentNodeMemoryOffset(), IsContainerGuardRequirement::NotRequired); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_parentNode); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodeNodeTypeDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeNodeTypeDOMJIT::callDOMGetter() +{ + Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create(); + patchpoint->effect = JSC::DOMJIT::Effect::forPure(); + patchpoint->requireGlobalObject = false; + patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { + JSValueRegs result = params[0].jsValueRegs(); + GPRReg node = params[1].gpr(); + jit.load8(CCallHelpers::Address(node, JSC::JSCell::typeInfoTypeOffset()), result.payloadGPR()); + jit.and32(CCallHelpers::TrustedImm32(JSNodeTypeMask), result.payloadGPR()); + jit.boxInt32(result.payloadGPR(), result); + return CCallHelpers::JumpList(); + }); + return patchpoint; +} + +Ref<JSC::DOMJIT::Patchpoint> NodeOwnerDocumentDOMJIT::checkDOM() +{ + return DOMJIT::checkDOM<Node>(); +} + +Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeOwnerDocumentDOMJIT::callDOMGetter() +{ + Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create(); + patchpoint->numGPScratchRegisters = 2; + patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { + JSValueRegs result = params[0].jsValueRegs(); + GPRReg node = params[1].gpr(); + GPRReg globalObject = params[2].gpr(); + JSValue globalObjectValue = params[2].value(); + GPRReg wrapped = params.gpScratch(0); + GPRReg document = params.gpScratch(1); + + jit.loadPtr(CCallHelpers::Address(node, JSNode::offsetOfWrapped()), wrapped); + DOMJIT::loadDocument(jit, wrapped, document); + RELEASE_ASSERT(!CAST_OFFSET(EventTarget*, Node*)); + RELEASE_ASSERT(!CAST_OFFSET(Node*, Document*)); + + CCallHelpers::JumpList nullCases; + // If the |this| is the document itself, ownerDocument will return null. + nullCases.append(jit.branchPtr(CCallHelpers::Equal, wrapped, document)); + DOMJIT::toWrapper<Document>(jit, params, document, globalObject, result, DOMJIT::toWrapperSlow<Document>, globalObjectValue); + auto done = jit.jump(); + + nullCases.link(&jit); + jit.moveValue(jsNull(), result); + done.link(&jit); + return CCallHelpers::JumpList(); + }); + patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_ownerDocument); + return patchpoint; +} + +} + +#endif diff --git a/Source/WebCore/domjit/generate-abstract-heap.rb b/Source/WebCore/domjit/generate-abstract-heap.rb new file mode 100644 index 000000000..b7412e85d --- /dev/null +++ b/Source/WebCore/domjit/generate-abstract-heap.rb @@ -0,0 +1,165 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- +# Copyright (C) 2016 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +require "yaml" + +class HeapRange + attr_reader :first, :last + def initialize(first, last) + @first = first + @last = last + end +end + +class AbstractHeap + attr_reader :range, :name, :parent + def initialize(name, tree) + @name = name + @parent = nil + if tree.nil? + @children = [] + else + @children = tree.map {|key, value| AbstractHeap.new(key, value) } + end + @range = nil + end + + def setParent(parent) + parent.children.push(self) + @parent = parent + end + + def compute(start) + current = start + if @children.empty? + @range = HeapRange.new(start, current + 1) + return + end + + @children.each {|child| + child.compute(current) + current = child.range.last + } + + @range = HeapRange.new(start, current) + end + + def dump output + shallowDump(output) + if @parent + output.print "-> " + @parent.dump(output) + end + end + + def shallowDump(output) + output.print "#{@name}<#{@range.first},#{@range.last}>" + end + + def deepDump output, indent + printIndent(output, indent) + shallowDump(output) + if @children.empty? + output.print "\n" + return + end + + output.print ":\n" + @children.each {|child| + child.deepDump(output, indent + 1) + } + end + + def generate output + output.puts "constexpr JSC::DOMJIT::HeapRange #{@name}(JSC::DOMJIT::HeapRange::ConstExpr, #{@range.first}, #{@range.last});" + @children.each {|child| + child.generate(output) + } + end + +private + def printIndent output, indent + indent.times { + output.print " " + } + end +end + +header = <<-EOS +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// Auto-generated file. Do not modify. + +#pragma once + +#include <domjit/DOMJITHeapRange.h> + +namespace WebCore { namespace DOMJIT { namespace AbstractHeapRepository { +EOS + +footer = <<-EOS +} } } +EOS + +$inputFileName = ARGV.shift +$outputFileName = ARGV.shift +File.open($outputFileName, "w") {|output| + File.open($inputFileName, "rb") {|file| + tree = YAML::load(file.read()) + heap = tree.map {|key, value| + AbstractHeap.new(key, value) + }.first + heap.compute(0) + + output.print(header) + output.puts("/* DOMJIT Abstract Heap Tree.") + heap.deepDump(output, 0) + output.puts("*/") + heap.generate(output) + output.print(footer) + } +} |