LeviLamina
Loading...
Searching...
No Matches
Closure.h
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <functional>
6
7#include "ll/api/memory/Memory.h"
8
9namespace ll::memory {
11public:
12 static constexpr size_t jitSize = 48;
13 struct PackedSelf {
14 char jitfn[jitSize];
15 ClosureBase* self;
16 };
17 DualMapping storage{};
18 LLNDAPI static void* getClosureData();
19 LLNDAPI ClosureBase(void const* impl);
20
21 ClosureBase(ClosureBase&&) = delete;
22 ClosureBase(ClosureBase const&) = delete;
23 ClosureBase& operator=(ClosureBase&&) = delete;
24 ClosureBase& operator=(ClosureBase const&) = delete;
25};
26
27template <class... Args>
29 static_assert(sizeof...(Args) < 0, "NativeClosure only accepts function types as template arguments.");
30};
31
32template <class Ret, class... Args>
33class NativeClosure<Ret(Args...)> : private ClosureBase {
34 static inline Ret closureImpl(Args... args) {
35 auto& self = *static_cast<NativeClosure*>(reinterpret_cast<PackedSelf*>(getClosureData())->self);
36 return (self.func)(self.data, std::forward<Args>(args)...);
37 }
38
39public:
40 using origin = Ret(uintptr_t, Args...);
41 using closure = Ret(Args...);
42
43 uintptr_t data;
44 origin* func;
45
46 [[nodiscard]] NativeClosure(origin* func, uintptr_t data) : ClosureBase(closureImpl), func(func), data(data) {}
47
48 [[nodiscard]] closure* get() const { return reinterpret_cast<closure*>(storage.executable()); }
49};
50template <class Ret, class... Args>
51NativeClosure(Ret (*)(uintptr_t, Args...), uintptr_t) -> NativeClosure<Ret(Args...)>;
52
53template <class... Args>
55 static_assert(sizeof...(Args) < 0, "FunctionalClosure only accepts function types as template arguments.");
56};
57template <class Ret, class... Args>
58class FunctionalClosure<Ret(Args...)> : private ClosureBase {
59 static inline Ret closureImpl(Args... args) {
60 auto& self = *static_cast<FunctionalClosure*>(reinterpret_cast<PackedSelf*>(getClosureData())->self);
61 return (self.func)(std::forward<Args>(args)...);
62 }
63
64public:
65 using closure = Ret(Args...);
66
67 std::function<closure> func;
68
69 [[nodiscard]] FunctionalClosure(std::function<closure> func) : ClosureBase(closureImpl), func(std::move(func)) {}
70
71 [[nodiscard]] closure* get() const { return reinterpret_cast<closure*>(storage.executable()); }
72};
73template <class Ret, class... Args>
74FunctionalClosure(Ret (*)(Args...)) -> FunctionalClosure<Ret(Args...)>;
75template <class T>
76FunctionalClosure(std::function<T>) -> FunctionalClosure<T>;
77} // namespace ll::memory
Definition Closure.h:10
Definition Memory.h:149
Definition Closure.h:54
Definition Closure.h:28