ce7b995dccdf608c427ac502085dba32142a43b8
[WebKit-https.git] / Source / JavaScriptCore / wasm / js / JSWebAssemblyCodeBlock.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(WEBASSEMBLY)
29
30 #include "JSCell.h"
31 #include "PromiseDeferredTimer.h"
32 #include "Structure.h"
33 #include "UnconditionalFinalizer.h"
34 #include "WasmCallee.h"
35 #include "WasmFormat.h"
36 #include "WasmModule.h"
37 #include <wtf/Bag.h>
38 #include <wtf/Vector.h>
39
40 namespace JSC {
41
42 class JSWebAssemblyModule;
43 class JSWebAssemblyMemory;
44
45 namespace Wasm {
46 class Plan;
47 }
48
49 class JSWebAssemblyCodeBlock final : public JSCell {
50 public:
51     typedef JSCell Base;
52     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
53
54     static JSWebAssemblyCodeBlock* create(VM&, Ref<Wasm::CodeBlock>, JSWebAssemblyModule*);
55     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
56     {
57         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
58     }
59
60     template<typename CellType>
61     static Subspace* subspaceFor(VM& vm)
62     {
63         return &vm.webAssemblyCodeBlockSpace;
64     }
65
66     unsigned functionImportCount() const { return m_codeBlock->functionImportCount(); }
67     JSWebAssemblyModule* module() const { return m_module.get(); }
68
69     bool isSafeToRun(JSWebAssemblyMemory*) const;
70
71     void finishCreation(VM&, JSWebAssemblyModule*);
72
73     // These two callee getters are only valid once the callees have been populated.
74
75     Wasm::Callee& jsEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
76     {
77         return m_codeBlock->jsEntrypointCalleeFromFunctionIndexSpace(functionIndexSpace);
78     }
79     Wasm::WasmEntrypointLoadLocation wasmEntrypointLoadLocationFromFunctionIndexSpace(unsigned functionIndexSpace)
80     {
81         return m_codeBlock->wasmEntrypointLoadLocationFromFunctionIndexSpace(functionIndexSpace);
82     }
83
84     Wasm::WasmEntrypointLoadLocation wasmToJsCallStubForImport(unsigned importIndex)
85     {
86         return &importWasmToJSStub(importIndex);
87     }
88
89     static ptrdiff_t offsetOfImportWasmToJSStub(unsigned importIndex)
90     {
91         return offsetOfImportStubs() + sizeof(void*) * importIndex;
92     }
93
94     Wasm::CodeBlock& codeBlock() { return m_codeBlock.get(); }
95
96     void clearJSCallICs(VM&);
97
98 private:
99     JSWebAssemblyCodeBlock(VM&, Ref<Wasm::CodeBlock>&&, const Wasm::ModuleInformation&);
100     DECLARE_EXPORT_INFO;
101     static const bool needsDestruction = true;
102     static void destroy(JSCell*);
103     static void visitChildren(JSCell*, SlotVisitor&);
104
105     static size_t offsetOfImportStubs()
106     {
107         return WTF::roundUpToMultipleOf<sizeof(void*)>(sizeof(JSWebAssemblyCodeBlock));
108     }
109
110     static size_t allocationSize(Checked<size_t> functionImportCount)
111     {
112         return (offsetOfImportStubs() + sizeof(void*) * functionImportCount).unsafeGet();
113     }
114
115     void*& importWasmToJSStub(unsigned importIndex)
116     {
117         return *bitwise_cast<void**>(bitwise_cast<char*>(this) + offsetOfImportWasmToJSStub(importIndex));
118     }
119
120     class UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
121         void finalizeUnconditionally() override;
122     };
123
124     Ref<Wasm::CodeBlock> m_codeBlock;
125     WriteBarrier<JSWebAssemblyModule> m_module;
126     Vector<MacroAssemblerCodeRef> m_wasmToJSExitStubs;
127     UnconditionalFinalizer m_unconditionalFinalizer;
128     Bag<CallLinkInfo> m_callLinkInfos;
129 };
130
131 } // namespace JSC
132
133 #endif // ENABLE(WEBASSEMBLY)