UNPKG

9.26 kBtext/x-cView Raw
1/*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the LICENSE
5 * file in the root directory of this source tree.
6 */
7#pragma once
8
9namespace facebook {
10namespace jsi {
11namespace detail {
12
13inline Value toValue(Runtime&, std::nullptr_t) {
14 return Value::null();
15}
16inline Value toValue(Runtime&, bool b) {
17 return Value(b);
18}
19inline Value toValue(Runtime&, double d) {
20 return Value(d);
21}
22inline Value toValue(Runtime&, float f) {
23 return Value(static_cast<double>(f));
24}
25inline Value toValue(Runtime&, int i) {
26 return Value(i);
27}
28inline Value toValue(Runtime& runtime, const char* str) {
29 return String::createFromAscii(runtime, str);
30}
31inline Value toValue(Runtime& runtime, const std::string& str) {
32 return String::createFromAscii(runtime, str);
33}
34template <typename T>
35inline Value toValue(Runtime& runtime, const T& other) {
36 static_assert(
37 std::is_base_of<Pointer, T>::value,
38 "This type cannot be converted to Value");
39 return Value(runtime, other);
40}
41inline Value toValue(Runtime& runtime, const Value& value) {
42 return Value(runtime, value);
43}
44inline Value&& toValue(Runtime&, Value&& value) {
45 return std::move(value);
46}
47
48inline PropNameID toPropNameID(Runtime& runtime, const char* name) {
49 return PropNameID::forAscii(runtime, name);
50}
51inline PropNameID toPropNameID(Runtime& runtime, const std::string& name) {
52 return PropNameID::forUtf8(runtime, name);
53}
54inline PropNameID&& toPropNameID(Runtime&, PropNameID&& name) {
55 return std::move(name);
56}
57
58void throwJSError(Runtime&, const char* msg);
59
60} // namespace detail
61
62template <typename T>
63inline T Runtime::make(Runtime::PointerValue* pv) {
64 return T(pv);
65}
66
67inline const Runtime::PointerValue* Runtime::getPointerValue(
68 const jsi::Pointer& pointer) {
69 return pointer.ptr_;
70}
71
72inline const Runtime::PointerValue* Runtime::getPointerValue(
73 const jsi::Value& value) {
74 return value.data_.pointer.ptr_;
75}
76
77inline Value Object::getProperty(Runtime& runtime, const char* name) const {
78 return getProperty(runtime, String::createFromAscii(runtime, name));
79}
80
81inline Value Object::getProperty(Runtime& runtime, const String& name) const {
82 return runtime.getProperty(*this, name);
83}
84
85inline Value Object::getProperty(Runtime& runtime, const PropNameID& name)
86 const {
87 return runtime.getProperty(*this, name);
88}
89
90inline bool Object::hasProperty(Runtime& runtime, const char* name) const {
91 return hasProperty(runtime, String::createFromAscii(runtime, name));
92}
93
94inline bool Object::hasProperty(Runtime& runtime, const String& name) const {
95 return runtime.hasProperty(*this, name);
96}
97
98inline bool Object::hasProperty(Runtime& runtime, const PropNameID& name)
99 const {
100 return runtime.hasProperty(*this, name);
101}
102
103template <typename T>
104void Object::setProperty(Runtime& runtime, const char* name, T&& value) {
105 setProperty(
106 runtime, String::createFromAscii(runtime, name), std::forward<T>(value));
107}
108
109template <typename T>
110void Object::setProperty(Runtime& runtime, const String& name, T&& value) {
111 setPropertyValue(
112 runtime, name, detail::toValue(runtime, std::forward<T>(value)));
113}
114
115template <typename T>
116void Object::setProperty(Runtime& runtime, const PropNameID& name, T&& value) {
117 setPropertyValue(
118 runtime, name, detail::toValue(runtime, std::forward<T>(value)));
119}
120
121inline Array Object::getArray(Runtime& runtime) const& {
122 assert(runtime.isArray(*this));
123 (void)runtime; // when assert is disabled we need to mark this as used
124 return Array(runtime.cloneObject(ptr_));
125}
126
127inline Array Object::getArray(Runtime& runtime) && {
128 assert(runtime.isArray(*this));
129 (void)runtime; // when assert is disabled we need to mark this as used
130 Runtime::PointerValue* value = ptr_;
131 ptr_ = nullptr;
132 return Array(value);
133}
134
135inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) const& {
136 assert(runtime.isArrayBuffer(*this));
137 (void)runtime; // when assert is disabled we need to mark this as used
138 return ArrayBuffer(runtime.cloneObject(ptr_));
139}
140
141inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && {
142 assert(runtime.isArrayBuffer(*this));
143 (void)runtime; // when assert is disabled we need to mark this as used
144 Runtime::PointerValue* value = ptr_;
145 ptr_ = nullptr;
146 return ArrayBuffer(value);
147}
148
149inline Function Object::getFunction(Runtime& runtime) const& {
150 assert(runtime.isFunction(*this));
151 return Function(runtime.cloneObject(ptr_));
152}
153
154inline Function Object::getFunction(Runtime& runtime) && {
155 assert(runtime.isFunction(*this));
156 (void)runtime; // when assert is disabled we need to mark this as used
157 Runtime::PointerValue* value = ptr_;
158 ptr_ = nullptr;
159 return Function(value);
160}
161
162template <typename T>
163inline bool Object::isHostObject(Runtime& runtime) const {
164 return runtime.isHostObject(*this) &&
165 std::dynamic_pointer_cast<T>(runtime.getHostObject(*this));
166}
167
168template <>
169inline bool Object::isHostObject<HostObject>(Runtime& runtime) const {
170 return runtime.isHostObject(*this);
171}
172
173template <typename T>
174inline std::shared_ptr<T> Object::getHostObject(Runtime& runtime) const {
175 assert(isHostObject<T>(runtime));
176 return std::static_pointer_cast<T>(runtime.getHostObject(*this));
177}
178
179template <typename T>
180inline std::shared_ptr<T> Object::asHostObject(Runtime& runtime) const {
181 if (!isHostObject<T>(runtime)) {
182 detail::throwJSError(runtime, "Object is not a HostObject of desired type");
183 }
184 return std::static_pointer_cast<T>(runtime.getHostObject(*this));
185}
186
187template <>
188inline std::shared_ptr<HostObject> Object::getHostObject<HostObject>(
189 Runtime& runtime) const {
190 assert(runtime.isHostObject(*this));
191 return runtime.getHostObject(*this);
192}
193
194inline Array Object::getPropertyNames(Runtime& runtime) const {
195 return runtime.getPropertyNames(*this);
196}
197
198inline Value WeakObject::lock(Runtime& runtime) {
199 return runtime.lockWeakObject(*this);
200}
201
202template <typename T>
203void Array::setValueAtIndex(Runtime& runtime, size_t i, T&& value) {
204 setValueAtIndexImpl(
205 runtime, i, detail::toValue(runtime, std::forward<T>(value)));
206}
207
208inline Value Array::getValueAtIndex(Runtime& runtime, size_t i) const {
209 return runtime.getValueAtIndex(*this, i);
210}
211
212inline Function Function::createFromHostFunction(
213 Runtime& runtime,
214 const jsi::PropNameID& name,
215 unsigned int paramCount,
216 jsi::HostFunctionType func) {
217 return runtime.createFunctionFromHostFunction(
218 name, paramCount, std::move(func));
219}
220
221inline Value Function::call(Runtime& runtime, const Value* args, size_t count)
222 const {
223 return runtime.call(*this, Value::undefined(), args, count);
224}
225
226inline Value Function::call(Runtime& runtime, std::initializer_list<Value> args)
227 const {
228 return call(runtime, args.begin(), args.size());
229}
230
231template <typename... Args>
232inline Value Function::call(Runtime& runtime, Args&&... args) const {
233 // A more awesome version of this would be able to create raw values
234 // which can be used directly without wrapping and unwrapping, but
235 // this will do for now.
236 return call(runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
237}
238
239inline Value Function::callWithThis(
240 Runtime& runtime,
241 const Object& jsThis,
242 const Value* args,
243 size_t count) const {
244 return runtime.call(*this, Value(runtime, jsThis), args, count);
245}
246
247inline Value Function::callWithThis(
248 Runtime& runtime,
249 const Object& jsThis,
250 std::initializer_list<Value> args) const {
251 return callWithThis(runtime, jsThis, args.begin(), args.size());
252}
253
254template <typename... Args>
255inline Value Function::callWithThis(
256 Runtime& runtime,
257 const Object& jsThis,
258 Args&&... args) const {
259 // A more awesome version of this would be able to create raw values
260 // which can be used directly without wrapping and unwrapping, but
261 // this will do for now.
262 return callWithThis(
263 runtime, jsThis, {detail::toValue(runtime, std::forward<Args>(args))...});
264}
265
266template <typename... Args>
267inline Array Array::createWithElements(Runtime& runtime, Args&&... args) {
268 return createWithElements(
269 runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
270}
271
272template <typename... Args>
273inline std::vector<PropNameID> PropNameID::names(
274 Runtime& runtime,
275 Args&&... args) {
276 return names({detail::toPropNameID(runtime, std::forward<Args>(args))...});
277}
278
279template <size_t N>
280inline std::vector<PropNameID> PropNameID::names(
281 PropNameID(&&propertyNames)[N]) {
282 std::vector<PropNameID> result;
283 result.reserve(N);
284 for (auto& name : propertyNames) {
285 result.push_back(std::move(name));
286 }
287 return result;
288}
289
290inline Value Function::callAsConstructor(
291 Runtime& runtime,
292 const Value* args,
293 size_t count) const {
294 return runtime.callAsConstructor(*this, args, count);
295}
296
297inline Value Function::callAsConstructor(
298 Runtime& runtime,
299 std::initializer_list<Value> args) const {
300 return callAsConstructor(runtime, args.begin(), args.size());
301}
302
303template <typename... Args>
304inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args)
305 const {
306 return callAsConstructor(
307 runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
308}
309
310} // namespace jsi
311} // namespace facebook