1/*
2 * Copyright (C) 2018 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#include "JSCJSValue.h"
29#include "JSCPtrTag.h"
30
31namespace JSC {
32
33class ExecState;
34
35typedef EncodedJSValue (JSC_HOST_CALL *RawNativeFunction)(ExecState*);
36
37class NativeFunction {
38public:
39 NativeFunction() = default;
40 NativeFunction(std::nullptr_t) : m_ptr(nullptr) { }
41 explicit NativeFunction(uintptr_t bits) : m_ptr(bitwise_cast<RawNativeFunction>(bits)) { }
42 NativeFunction(RawNativeFunction other) : m_ptr(other) { }
43
44 explicit operator intptr_t() const { return reinterpret_cast<intptr_t>(m_ptr); }
45 explicit operator bool() const { return !!m_ptr; }
46 bool operator!() const { return !m_ptr; }
47 bool operator==(NativeFunction other) const { return m_ptr == other.m_ptr; }
48 bool operator!=(NativeFunction other) const { return m_ptr == other.m_ptr; }
49
50 EncodedJSValue operator()(ExecState* exec) { return m_ptr(exec); }
51
52 void* rawPointer() const { return reinterpret_cast<void*>(m_ptr); }
53
54private:
55 RawNativeFunction m_ptr;
56
57 friend class TaggedNativeFunction;
58};
59
60struct NativeFunctionHash {
61 static unsigned hash(NativeFunction key) { return IntHash<uintptr_t>::hash(bitwise_cast<uintptr_t>(key)); }
62 static bool equal(NativeFunction a, NativeFunction b) { return a == b; }
63 static const bool safeToCompareToEmptyOrDeleted = true;
64};
65
66class TaggedNativeFunction {
67public:
68 TaggedNativeFunction() = default;
69 TaggedNativeFunction(std::nullptr_t) : m_ptr(nullptr) { }
70 explicit TaggedNativeFunction(intptr_t bits) : m_ptr(bitwise_cast<void*>(bits)) { }
71
72 TaggedNativeFunction(NativeFunction func)
73 : m_ptr(tagCFunctionPtr<void*, JSEntryPtrTag>(func.m_ptr))
74 { }
75 TaggedNativeFunction(RawNativeFunction func)
76 : m_ptr(tagCFunctionPtr<void*, JSEntryPtrTag>(func))
77 { }
78
79 explicit operator bool() const { return !!m_ptr; }
80 bool operator!() const { return !m_ptr; }
81 bool operator==(TaggedNativeFunction other) const { return m_ptr == other.m_ptr; }
82 bool operator!=(TaggedNativeFunction other) const { return m_ptr != other.m_ptr; }
83
84 EncodedJSValue operator()(ExecState* exec) { return NativeFunction(*this)(exec); }
85
86 explicit operator NativeFunction()
87 {
88 ASSERT(m_ptr);
89 return untagCFunctionPtr<NativeFunction, JSEntryPtrTag>(m_ptr);
90 }
91
92 void* rawPointer() const { return m_ptr; }
93
94private:
95 void* m_ptr;
96};
97
98struct TaggedNativeFunctionHash {
99 static unsigned hash(TaggedNativeFunction key) { return IntHash<uintptr_t>::hash(bitwise_cast<uintptr_t>(key)); }
100 static bool equal(TaggedNativeFunction a, TaggedNativeFunction b) { return a == b; }
101 static const bool safeToCompareToEmptyOrDeleted = true;
102};
103
104static_assert(sizeof(NativeFunction) == sizeof(void*), "");
105static_assert(sizeof(TaggedNativeFunction) == sizeof(void*), "");
106
107} // namespace JSC
108
109namespace WTF {
110
111template<typename T> struct DefaultHash;
112template<> struct DefaultHash<JSC::NativeFunction> {
113 using Hash = JSC::NativeFunctionHash;
114};
115
116template<typename T> struct DefaultHash;
117template<> struct DefaultHash<JSC::TaggedNativeFunction> {
118 using Hash = JSC::TaggedNativeFunctionHash;
119};
120
121} // namespace WTF
122
123