[CMake] Fix typo in version variable assingment in FindWOFF2.cmake
[WebKit.git] / Source / JavaScriptCore / wasm / WasmSignature.h
1 /*
2  * Copyright (C) 2016-2019 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 "B3Type.h"
31 #include "WasmOps.h"
32 #include <cstdint>
33 #include <cstring>
34 #include <wtf/CheckedArithmetic.h>
35 #include <wtf/HashMap.h>
36 #include <wtf/HashSet.h>
37 #include <wtf/HashTraits.h>
38 #include <wtf/StdLibExtras.h>
39 #include <wtf/ThreadSafeRefCounted.h>
40 #include <wtf/Vector.h>
41
42 namespace WTF {
43 class PrintStream;
44 }
45
46 namespace JSC {
47
48 namespace Wasm {
49
50 using SignatureArgCount = uint32_t;
51 using SignatureIndex = uint64_t;
52
53 class Signature : public ThreadSafeRefCounted<Signature> {
54     WTF_MAKE_FAST_ALLOCATED;
55
56     Signature() = delete;
57     Signature(const Signature&) = delete;
58     Signature(SignatureArgCount retCount, SignatureArgCount argCount)
59         : m_retCount(retCount)
60         , m_argCount(argCount)
61     {
62     }
63
64     Type* storage(SignatureArgCount i)
65     {
66         return i + reinterpret_cast<Type*>(reinterpret_cast<char*>(this) + sizeof(Signature));
67     }
68     Type* storage(SignatureArgCount i) const { return const_cast<Signature*>(this)->storage(i); }
69     static size_t allocatedSize(Checked<SignatureArgCount> retCount, Checked<SignatureArgCount> argCount)
70     {
71         return (sizeof(Signature) + (retCount + argCount) * sizeof(Type)).unsafeGet();
72     }
73
74 public:
75     SignatureArgCount returnCount() const { return m_retCount; }
76     SignatureArgCount argumentCount() const { return m_argCount; }
77
78     Type returnType(SignatureArgCount i) const { ASSERT(i < returnCount()); return const_cast<Signature*>(this)->getReturnType(i); }
79     bool returnsVoid() const { return !returnCount(); }
80     Type argument(SignatureArgCount i) const { return const_cast<Signature*>(this)->getArgument(i); }
81     SignatureIndex index() const { return bitwise_cast<SignatureIndex>(this); }
82
83     WTF::String toString() const;
84     void dump(WTF::PrintStream& out) const;
85     bool operator==(const Signature& rhs) const { return this == &rhs; }
86     unsigned hash() const;
87
88     // Signatures are uniqued and, for call_indirect, validated at runtime. Tables can create invalid SignatureIndex values which cause call_indirect to fail. We use 0 as the invalidIndex so that the codegen can easily test for it and trap, and we add a token invalid entry in SignatureInformation.
89     static const constexpr SignatureIndex invalidIndex = 0;
90
91 private:
92     friend class SignatureInformation;
93     friend struct ParameterTypes;
94
95     static RefPtr<Signature> tryCreate(SignatureArgCount returnCount, SignatureArgCount argumentCount);
96     Type& getReturnType(SignatureArgCount i) { ASSERT(i < returnCount()); return *storage(i); }
97     Type& getArgument(SignatureArgCount i) { ASSERT(i < argumentCount()); return *storage(returnCount() + i); }
98
99     SignatureArgCount m_retCount;
100     SignatureArgCount m_argCount;
101     // Return Type and arguments are stored here.
102 };
103
104 struct SignatureHash {
105     RefPtr<Signature> key { nullptr };
106     SignatureHash() = default;
107     explicit SignatureHash(Ref<Signature>&& key)
108         : key(WTFMove(key))
109     { }
110     explicit SignatureHash(WTF::HashTableDeletedValueType)
111         : key(WTF::HashTableDeletedValue)
112     { }
113     bool operator==(const SignatureHash& rhs) const { return equal(*this, rhs); }
114     static bool equal(const SignatureHash& lhs, const SignatureHash& rhs) { return lhs.key == rhs.key; }
115     static unsigned hash(const SignatureHash& signature) { return signature.key ? signature.key->hash() : 0; }
116     static constexpr bool safeToCompareToEmptyOrDeleted = false;
117     bool isHashTableDeletedValue() const { return key.isHashTableDeletedValue(); }
118 };
119
120 } } // namespace JSC::Wasm
121
122
123 namespace WTF {
124
125 template<typename T> struct DefaultHash;
126 template<> struct DefaultHash<JSC::Wasm::SignatureHash> {
127     typedef JSC::Wasm::SignatureHash Hash;
128 };
129
130 template<typename T> struct HashTraits;
131 template<> struct HashTraits<JSC::Wasm::SignatureHash> : SimpleClassHashTraits<JSC::Wasm::SignatureHash> {
132     static constexpr bool emptyValueIsZero = true;
133 };
134
135 } // namespace WTF
136
137
138 namespace JSC { namespace Wasm {
139
140 // Signature information is held globally and shared by the entire process to allow all signatures to be unique. This is required when wasm calls another wasm instance, and must work when modules are shared between multiple VMs.
141 class SignatureInformation {
142     WTF_MAKE_NONCOPYABLE(SignatureInformation);
143     WTF_MAKE_FAST_ALLOCATED;
144
145     SignatureInformation();
146
147 public:
148     static SignatureInformation& singleton();
149
150     static RefPtr<Signature> signatureFor(const Vector<Type, 1>& returnTypes, const Vector<Type>& argumentTypes);
151     ALWAYS_INLINE const Signature* thunkFor(Type type) const { return thunkSignatures[linearizeType(type)]; }
152
153     static const Signature& get(SignatureIndex);
154     static SignatureIndex get(const Signature&);
155     static void tryCleanup();
156
157 private:
158     HashSet<Wasm::SignatureHash> m_signatureSet;
159     const Signature* thunkSignatures[numTypes];
160     Lock m_lock;
161
162     JS_EXPORT_PRIVATE static SignatureInformation* theOne;
163     JS_EXPORT_PRIVATE static std::once_flag signatureInformationFlag;
164 };
165
166 } } // namespace JSC::Wasm
167
168 #endif // ENABLE(WEBASSEMBLY)