| 1 | /* |
| 2 | * Copyright (C) 2016 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. AND ITS CONTRIBUTORS ``AS IS'' |
| 14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| 17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 23 | * THE POSSIBILITY OF SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #pragma once |
| 27 | |
| 28 | #include "StringAdaptors.h" |
| 29 | #include <JavaScriptCore/HandleTypes.h> |
| 30 | #include <JavaScriptCore/Strong.h> |
| 31 | #include <wtf/Brigand.h> |
| 32 | #include <wtf/HashMap.h> |
| 33 | #include <wtf/StdLibExtras.h> |
| 34 | #include <wtf/text/WTFString.h> |
| 35 | |
| 36 | #if ENABLE(WEBGL) |
| 37 | #include "WebGLAny.h" |
| 38 | #endif |
| 39 | |
| 40 | namespace JSC { |
| 41 | class ArrayBuffer; |
| 42 | class ArrayBufferView; |
| 43 | class DataView; |
| 44 | class JSValue; |
| 45 | class JSObject; |
| 46 | template<typename> class Strong; |
| 47 | } |
| 48 | |
| 49 | namespace WebCore { |
| 50 | |
| 51 | class IDBKey; |
| 52 | class IDBKeyData; |
| 53 | class IDBValue; |
| 54 | class JSWindowProxy; |
| 55 | class DOMPromise; |
| 56 | class ScheduledAction; |
| 57 | |
| 58 | #if ENABLE(WEBGL) |
| 59 | class WebGLExtension; |
| 60 | #endif |
| 61 | |
| 62 | template<typename T> |
| 63 | struct IDLType { |
| 64 | using ImplementationType = T; |
| 65 | using StorageType = T; |
| 66 | |
| 67 | using ParameterType = T; |
| 68 | using NullableParameterType = Optional<ImplementationType>; |
| 69 | |
| 70 | using InnerParameterType = T; |
| 71 | using NullableInnerParameterType = Optional<ImplementationType>; |
| 72 | |
| 73 | using NullableType = Optional<ImplementationType>; |
| 74 | static NullableType nullValue() { return WTF::nullopt; } |
| 75 | static bool isNullValue(const NullableType& value) { return !value; } |
| 76 | static ImplementationType (const NullableType& value) { return value.value(); } |
| 77 | }; |
| 78 | |
| 79 | // IDLUnsupportedType is a special type that serves as a base class for currently unsupported types. |
| 80 | struct IDLUnsupportedType : IDLType<void> { }; |
| 81 | |
| 82 | // IDLNull is a special type for use as a subtype in an IDLUnion that is nullable. |
| 83 | struct IDLNull : IDLType<std::nullptr_t> { }; |
| 84 | |
| 85 | struct IDLAny : IDLType<JSC::Strong<JSC::Unknown>> { |
| 86 | using ParameterType = JSC::JSValue; |
| 87 | using NullableParameterType = JSC::JSValue; |
| 88 | |
| 89 | using NullableType = JSC::Strong<JSC::Unknown>; |
| 90 | static inline std::nullptr_t nullValue() { return nullptr; } |
| 91 | template<typename U> static inline bool isNullValue(U&& value) { return !value; } |
| 92 | template<typename U> static inline U&& (U&& value) { return std::forward<U>(value); } |
| 93 | }; |
| 94 | |
| 95 | struct IDLVoid : IDLType<void> { }; |
| 96 | |
| 97 | struct IDLBoolean : IDLType<bool> { }; |
| 98 | |
| 99 | template<typename NumericType> struct IDLNumber : IDLType<NumericType> { }; |
| 100 | |
| 101 | template<typename IntegerType> struct IDLInteger : IDLNumber<IntegerType> { }; |
| 102 | struct IDLByte : IDLInteger<int8_t> { }; |
| 103 | struct IDLOctet : IDLInteger<uint8_t> { }; |
| 104 | struct IDLShort : IDLInteger<int16_t> { }; |
| 105 | struct IDLUnsignedShort : IDLInteger<uint16_t> { }; |
| 106 | struct IDLLong : IDLInteger<int32_t> { }; |
| 107 | struct IDLUnsignedLong : IDLInteger<uint32_t> { }; |
| 108 | struct IDLLongLong : IDLInteger<int64_t> { }; |
| 109 | struct IDLUnsignedLongLong : IDLInteger<uint64_t> { }; |
| 110 | |
| 111 | template<typename T> struct IDLClampAdaptor : IDLInteger<typename T::ImplementationType> { |
| 112 | using InnerType = T; |
| 113 | }; |
| 114 | |
| 115 | template<typename T> struct IDLEnforceRangeAdaptor : IDLInteger<typename T::ImplementationType> { |
| 116 | using InnerType = T; |
| 117 | }; |
| 118 | |
| 119 | template<typename FloatingPointType> struct IDLFloatingPoint : IDLNumber<FloatingPointType> { }; |
| 120 | struct IDLFloat : IDLFloatingPoint<float> { }; |
| 121 | struct IDLUnrestrictedFloat : IDLFloatingPoint<float> { }; |
| 122 | struct IDLDouble : IDLFloatingPoint<double> { }; |
| 123 | struct IDLUnrestrictedDouble : IDLFloatingPoint<double> { }; |
| 124 | |
| 125 | template<typename StringType> struct IDLString : IDLType<StringType> { |
| 126 | using ParameterType = const StringType&; |
| 127 | using NullableParameterType = const StringType&; |
| 128 | |
| 129 | using NullableType = StringType; |
| 130 | static StringType nullValue() { return StringType(); } |
| 131 | static bool isNullValue(const StringType& value) { return value.isNull(); } |
| 132 | static bool isNullValue(const UncachedString& value) { return value.string.isNull(); } |
| 133 | static bool isNullValue(const OwnedString& value) { return value.string.isNull(); } |
| 134 | template <typename U> static U&& (U&& value) { return std::forward<U>(value); } |
| 135 | }; |
| 136 | struct IDLDOMString : IDLString<String> { }; |
| 137 | struct IDLByteString : IDLString<String> { }; |
| 138 | struct IDLUSVString : IDLString<String> { }; |
| 139 | |
| 140 | template<typename T> struct IDLTreatNullAsEmptyAdaptor : IDLString<String> { |
| 141 | using InnerType = T; |
| 142 | }; |
| 143 | |
| 144 | template<typename T> struct IDLAtomicStringAdaptor : IDLString<AtomicString> { |
| 145 | using InnerType = T; |
| 146 | }; |
| 147 | |
| 148 | template<typename T> struct IDLRequiresExistingAtomicStringAdaptor : IDLString<AtomicString> { |
| 149 | using InnerType = T; |
| 150 | }; |
| 151 | |
| 152 | struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> { |
| 153 | using NullableType = JSC::Strong<JSC::JSObject>; |
| 154 | |
| 155 | static inline NullableType nullValue() { return { }; } |
| 156 | template<typename U> static inline bool isNullValue(U&& value) { return !value; } |
| 157 | template<typename U> static inline U&& (U&& value) { return std::forward<U>(value); } |
| 158 | }; |
| 159 | |
| 160 | template<typename T> struct IDLWrapper : IDLType<RefPtr<T>> { |
| 161 | using RawType = T; |
| 162 | |
| 163 | using StorageType = Ref<T>; |
| 164 | |
| 165 | using ParameterType = T&; |
| 166 | using NullableParameterType = T*; |
| 167 | |
| 168 | using InnerParameterType = Ref<T>; |
| 169 | using NullableInnerParameterType = RefPtr<T>; |
| 170 | |
| 171 | using NullableType = RefPtr<T>; |
| 172 | static inline std::nullptr_t nullValue() { return nullptr; } |
| 173 | template<typename U> static inline bool isNullValue(U&& value) { return !value; } |
| 174 | template<typename U> static inline U&& (U&& value) { return std::forward<U>(value); } |
| 175 | }; |
| 176 | |
| 177 | template<typename T> struct IDLInterface : IDLWrapper<T> { }; |
| 178 | template<typename T> struct IDLCallbackInterface : IDLWrapper<T> { }; |
| 179 | template<typename T> struct IDLCallbackFunction : IDLWrapper<T> { }; |
| 180 | |
| 181 | template<typename T> struct IDLDictionary : IDLType<T> { |
| 182 | using ParameterType = const T&; |
| 183 | using NullableParameterType = const T&; |
| 184 | }; |
| 185 | |
| 186 | template<typename T> struct IDLEnumeration : IDLType<T> { }; |
| 187 | |
| 188 | template<typename T> struct IDLNullable : IDLType<typename T::NullableType> { |
| 189 | using InnerType = T; |
| 190 | |
| 191 | using ParameterType = typename T::NullableParameterType; |
| 192 | using NullableParameterType = typename T::NullableParameterType; |
| 193 | |
| 194 | using InnerParameterType = typename T::NullableInnerParameterType; |
| 195 | using NullableInnerParameterType = typename T::NullableInnerParameterType; |
| 196 | |
| 197 | using NullableType = typename T::NullableType; |
| 198 | static inline auto nullValue() -> decltype(T::nullValue()) { return T::nullValue(); } |
| 199 | template<typename U> static inline bool isNullValue(U&& value) { return T::isNullValue(std::forward<U>(value)); } |
| 200 | template<typename U> static inline auto (U&& value) -> decltype(T::extractValueFromNullable(std::forward<U>(value))) { return T::extractValueFromNullable(std::forward<U>(value)); } |
| 201 | }; |
| 202 | |
| 203 | template<typename T> struct IDLSequence : IDLType<Vector<typename T::ImplementationType>> { |
| 204 | using InnerType = T; |
| 205 | |
| 206 | using ParameterType = const Vector<typename T::InnerParameterType>&; |
| 207 | using NullableParameterType = const Optional<Vector<typename T::InnerParameterType>>&; |
| 208 | }; |
| 209 | |
| 210 | template<typename T> struct IDLFrozenArray : IDLType<Vector<typename T::ImplementationType>> { |
| 211 | using InnerType = T; |
| 212 | |
| 213 | using ParameterType = const Vector<typename T::ImplementationType>&; |
| 214 | using NullableParameterType = const Optional<Vector<typename T::ImplementationType>>&; |
| 215 | }; |
| 216 | |
| 217 | template<typename K, typename V> struct IDLRecord : IDLType<Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>> { |
| 218 | using KeyType = K; |
| 219 | using ValueType = V; |
| 220 | |
| 221 | using ParameterType = const Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>&; |
| 222 | using NullableParameterType = const Optional<Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>>&; |
| 223 | }; |
| 224 | |
| 225 | template<typename T> struct IDLPromise : IDLWrapper<DOMPromise> { |
| 226 | using InnerType = T; |
| 227 | }; |
| 228 | |
| 229 | struct IDLError : IDLUnsupportedType { }; |
| 230 | struct IDLDOMException : IDLUnsupportedType { }; |
| 231 | |
| 232 | template<typename... Ts> |
| 233 | struct IDLUnion : IDLType<Variant<typename Ts::ImplementationType...>> { |
| 234 | using TypeList = brigand::list<Ts...>; |
| 235 | |
| 236 | using ParameterType = const Variant<typename Ts::ImplementationType...>&; |
| 237 | using NullableParameterType = const Optional<Variant<typename Ts::ImplementationType...>>&; |
| 238 | }; |
| 239 | |
| 240 | template<typename T> struct IDLBufferSource : IDLWrapper<T> { }; |
| 241 | |
| 242 | struct IDLArrayBuffer : IDLBufferSource<JSC::ArrayBuffer> { }; |
| 243 | // NOTE: WebIDL defines ArrayBufferView as an IDL union of all the TypedArray types. |
| 244 | // and DataView. For convience in our implementation, we give it a distinct |
| 245 | // type that maps to the shared based class of all those classes. |
| 246 | struct IDLArrayBufferView : IDLBufferSource<JSC::ArrayBufferView> { }; |
| 247 | struct IDLDataView : IDLBufferSource<JSC::DataView> { }; |
| 248 | |
| 249 | template<typename T> struct IDLTypedArray : IDLBufferSource<T> { }; |
| 250 | // NOTE: The specific typed array types are IDLTypedArray specialized on the typed array |
| 251 | // implementation type, e.g. IDLFloat64Array is IDLTypedArray<JSC::Float64Array> |
| 252 | |
| 253 | |
| 254 | // Non-WebIDL extensions |
| 255 | |
| 256 | struct IDLDate : IDLType<double> { |
| 257 | using NullableType = double; |
| 258 | static double nullValue() { return std::numeric_limits<double>::quiet_NaN(); } |
| 259 | static bool isNullValue(double value) { return std::isnan(value); } |
| 260 | static double (double value) { return value; } |
| 261 | }; |
| 262 | |
| 263 | struct IDLJSON : IDLType<String> { |
| 264 | using ParameterType = const String&; |
| 265 | using NullableParameterType = const String&; |
| 266 | |
| 267 | using NullableType = String; |
| 268 | static String nullValue() { return String(); } |
| 269 | static bool isNullValue(const String& value) { return value.isNull(); } |
| 270 | template <typename U> static U&& (U&& value) { return std::forward<U>(value); } |
| 271 | }; |
| 272 | |
| 273 | struct IDLScheduledAction : IDLType<std::unique_ptr<ScheduledAction>> { }; |
| 274 | template<typename T> struct IDLSerializedScriptValue : IDLWrapper<T> { }; |
| 275 | template<typename T> struct IDLEventListener : IDLWrapper<T> { }; |
| 276 | template<typename T> struct IDLXPathNSResolver : IDLWrapper<T> { }; |
| 277 | |
| 278 | struct IDLIDBKey : IDLWrapper<IDBKey> { }; |
| 279 | struct IDLIDBKeyData : IDLWrapper<IDBKeyData> { }; |
| 280 | struct IDLIDBValue : IDLWrapper<IDBValue> { }; |
| 281 | |
| 282 | #if ENABLE(WEBGL) |
| 283 | struct IDLWebGLAny : IDLType<WebGLAny> { }; |
| 284 | struct IDLWebGLExtension : IDLWrapper<WebGLExtension> { }; |
| 285 | #endif |
| 286 | |
| 287 | // Helper predicates |
| 288 | |
| 289 | template<typename T> |
| 290 | struct IsIDLInterface : public std::integral_constant<bool, WTF::IsTemplate<T, IDLInterface>::value> { }; |
| 291 | |
| 292 | template<typename T> |
| 293 | struct IsIDLDictionary : public std::integral_constant<bool, WTF::IsTemplate<T, IDLDictionary>::value> { }; |
| 294 | |
| 295 | template<typename T> |
| 296 | struct IsIDLEnumeration : public std::integral_constant<bool, WTF::IsTemplate<T, IDLEnumeration>::value> { }; |
| 297 | |
| 298 | template<typename T> |
| 299 | struct IsIDLSequence : public std::integral_constant<bool, WTF::IsTemplate<T, IDLSequence>::value> { }; |
| 300 | |
| 301 | template<typename T> |
| 302 | struct IsIDLFrozenArray : public std::integral_constant<bool, WTF::IsTemplate<T, IDLFrozenArray>::value> { }; |
| 303 | |
| 304 | template<typename T> |
| 305 | struct IsIDLRecord : public std::integral_constant<bool, WTF::IsTemplate<T, IDLRecord>::value> { }; |
| 306 | |
| 307 | template<typename T> |
| 308 | struct IsIDLString : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLString, T>::value> { }; |
| 309 | |
| 310 | template<typename T> |
| 311 | struct IsIDLStringOrEnumeration : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLString, T>::value || WTF::IsTemplate<T, IDLEnumeration>::value> { }; |
| 312 | |
| 313 | template<typename T> |
| 314 | struct IsIDLNumber : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLNumber, T>::value> { }; |
| 315 | |
| 316 | template<typename T> |
| 317 | struct IsIDLInteger : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLInteger, T>::value> { }; |
| 318 | |
| 319 | template<typename T> |
| 320 | struct IsIDLFloatingPoint : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLFloatingPoint, T>::value> { }; |
| 321 | |
| 322 | template<typename T> |
| 323 | struct IsIDLTypedArray : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLTypedArray, T>::value> { }; |
| 324 | |
| 325 | } // namespace WebCore |
| 326 | |