1*ec63e07aSXin Li // Copyright 2019 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li
15*ec63e07aSXin Li #ifndef SANDBOXED_API_VAR_REG_H_
16*ec63e07aSXin Li #define SANDBOXED_API_VAR_REG_H_
17*ec63e07aSXin Li
18*ec63e07aSXin Li #include <algorithm>
19*ec63e07aSXin Li #include <cstring>
20*ec63e07aSXin Li #include <iostream>
21*ec63e07aSXin Li #include <string>
22*ec63e07aSXin Li #include <type_traits>
23*ec63e07aSXin Li
24*ec63e07aSXin Li #include "absl/strings/str_format.h"
25*ec63e07aSXin Li #include "sandboxed_api/var_abstract.h"
26*ec63e07aSXin Li
27*ec63e07aSXin Li namespace sapi::v {
28*ec63e07aSXin Li
29*ec63e07aSXin Li // The super-class for Reg. Specified as a class, so it can be used as a
30*ec63e07aSXin Li // type specifier in methods.
31*ec63e07aSXin Li class Callable : public Var {
32*ec63e07aSXin Li public:
33*ec63e07aSXin Li // Get pointer to the stored data.
34*ec63e07aSXin Li virtual const void* GetDataPtr() = 0;
35*ec63e07aSXin Li
36*ec63e07aSXin Li // Set internal data from ptr.
37*ec63e07aSXin Li virtual void SetDataFromPtr(const void* ptr, size_t max_sz) = 0;
38*ec63e07aSXin Li
39*ec63e07aSXin Li // Get data from internal ptr.
GetDataFromPtr(void * ptr,size_t max_sz)40*ec63e07aSXin Li void GetDataFromPtr(void* ptr, size_t max_sz) {
41*ec63e07aSXin Li size_t min_sz = std::min<size_t>(GetSize(), max_sz);
42*ec63e07aSXin Li memcpy(ptr, GetDataPtr(), min_sz);
43*ec63e07aSXin Li }
44*ec63e07aSXin Li
45*ec63e07aSXin Li protected:
46*ec63e07aSXin Li Callable() = default;
47*ec63e07aSXin Li };
48*ec63e07aSXin Li
49*ec63e07aSXin Li // class Reg represents register-sized variables.
50*ec63e07aSXin Li template <typename T>
51*ec63e07aSXin Li class Reg : public Callable {
52*ec63e07aSXin Li public:
53*ec63e07aSXin Li static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> ||
54*ec63e07aSXin Li std::is_pointer_v<T> || std::is_enum_v<T>,
55*ec63e07aSXin Li "Only register-sized types are allowed as template argument "
56*ec63e07aSXin Li "for class Reg.");
57*ec63e07aSXin Li
58*ec63e07aSXin Li explicit Reg(const T value = {}) {
59*ec63e07aSXin Li value_ = value;
60*ec63e07aSXin Li SetLocal(&value_);
61*ec63e07aSXin Li }
62*ec63e07aSXin Li
63*ec63e07aSXin Li // Getter/Setter for the stored value.
GetValue()64*ec63e07aSXin Li virtual T GetValue() const { return value_; }
SetValue(T value)65*ec63e07aSXin Li virtual void SetValue(T value) { value_ = value; }
66*ec63e07aSXin Li
GetDataPtr()67*ec63e07aSXin Li const void* GetDataPtr() override {
68*ec63e07aSXin Li return reinterpret_cast<const void*>(&value_);
69*ec63e07aSXin Li }
SetDataFromPtr(const void * ptr,size_t max_sz)70*ec63e07aSXin Li void SetDataFromPtr(const void* ptr, size_t max_sz) override {
71*ec63e07aSXin Li memcpy(&value_, ptr, std::min(GetSize(), max_sz));
72*ec63e07aSXin Li }
73*ec63e07aSXin Li
GetSize()74*ec63e07aSXin Li size_t GetSize() const override { return sizeof(T); }
75*ec63e07aSXin Li
76*ec63e07aSXin Li Type GetType() const override;
77*ec63e07aSXin Li
78*ec63e07aSXin Li std::string GetTypeString() const override;
79*ec63e07aSXin Li
80*ec63e07aSXin Li std::string ToString() const override;
81*ec63e07aSXin Li
82*ec63e07aSXin Li protected:
83*ec63e07aSXin Li // The stored value.
84*ec63e07aSXin Li T value_;
85*ec63e07aSXin Li };
86*ec63e07aSXin Li
87*ec63e07aSXin Li template <typename T>
GetType()88*ec63e07aSXin Li Type Reg<T>::GetType() const {
89*ec63e07aSXin Li if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
90*ec63e07aSXin Li return Type::kInt;
91*ec63e07aSXin Li }
92*ec63e07aSXin Li if constexpr (std::is_floating_point_v<T>) {
93*ec63e07aSXin Li return Type::kFloat;
94*ec63e07aSXin Li }
95*ec63e07aSXin Li if constexpr (std::is_pointer_v<T>) {
96*ec63e07aSXin Li return Type::kPointer;
97*ec63e07aSXin Li }
98*ec63e07aSXin Li // Not reached
99*ec63e07aSXin Li }
100*ec63e07aSXin Li
101*ec63e07aSXin Li template <typename T>
GetTypeString()102*ec63e07aSXin Li std::string Reg<T>::GetTypeString() const {
103*ec63e07aSXin Li if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
104*ec63e07aSXin Li return "Integer";
105*ec63e07aSXin Li }
106*ec63e07aSXin Li if constexpr (std::is_floating_point_v<T>) {
107*ec63e07aSXin Li return "Floating-point";
108*ec63e07aSXin Li }
109*ec63e07aSXin Li if constexpr (std::is_pointer_v<T>) {
110*ec63e07aSXin Li return "Pointer";
111*ec63e07aSXin Li }
112*ec63e07aSXin Li // Not reached
113*ec63e07aSXin Li }
114*ec63e07aSXin Li
115*ec63e07aSXin Li template <typename T>
ToString()116*ec63e07aSXin Li std::string Reg<T>::ToString() const {
117*ec63e07aSXin Li if constexpr (std::is_integral_v<T>) {
118*ec63e07aSXin Li return std::to_string(value_);
119*ec63e07aSXin Li }
120*ec63e07aSXin Li if constexpr (std::is_enum_v<T>) {
121*ec63e07aSXin Li return std::to_string(static_cast<std::underlying_type_t<T>>(value_));
122*ec63e07aSXin Li }
123*ec63e07aSXin Li if constexpr (std::is_floating_point_v<T>) {
124*ec63e07aSXin Li return absl::StrFormat("%.10f", value_);
125*ec63e07aSXin Li }
126*ec63e07aSXin Li if constexpr (std::is_pointer<T>::value) {
127*ec63e07aSXin Li return absl::StrFormat("%p", value_);
128*ec63e07aSXin Li }
129*ec63e07aSXin Li // Not reached.
130*ec63e07aSXin Li }
131*ec63e07aSXin Li
132*ec63e07aSXin Li } // namespace sapi::v
133*ec63e07aSXin Li
134*ec63e07aSXin Li #endif // SANDBOXED_API_VAR_REG_H_
135