/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once namespace facebook { namespace jsi { namespace detail { inline Value toValue(Runtime&, std::nullptr_t) { return Value::null(); } inline Value toValue(Runtime&, bool b) { return Value(b); } inline Value toValue(Runtime&, double d) { return Value(d); } inline Value toValue(Runtime&, float f) { return Value(static_cast(f)); } inline Value toValue(Runtime&, int i) { return Value(i); } inline Value toValue(Runtime& runtime, const char* str) { return String::createFromAscii(runtime, str); } inline Value toValue(Runtime& runtime, const std::string& str) { return String::createFromUtf8(runtime, str); } template inline Value toValue(Runtime& runtime, const T& other) { static_assert( std::is_base_of::value, "This type cannot be converted to Value"); return Value(runtime, other); } inline Value toValue(Runtime& runtime, const Value& value) { return Value(runtime, value); } inline Value&& toValue(Runtime&, Value&& value) { return std::move(value); } inline PropNameID toPropNameID(Runtime& runtime, const char* name) { return PropNameID::forAscii(runtime, name); } inline PropNameID toPropNameID(Runtime& runtime, const std::string& name) { return PropNameID::forUtf8(runtime, name); } inline PropNameID&& toPropNameID(Runtime&, PropNameID&& name) { return std::move(name); } void throwJSError(Runtime&, const char* msg); } // namespace detail template inline T Runtime::make(Runtime::PointerValue* pv) { return T(pv); } inline Runtime::PointerValue* Runtime::getPointerValue(jsi::Pointer& pointer) { return pointer.ptr_; } inline const Runtime::PointerValue* Runtime::getPointerValue( const jsi::Pointer& pointer) { return pointer.ptr_; } inline const Runtime::PointerValue* Runtime::getPointerValue( const jsi::Value& value) { return value.data_.pointer.ptr_; } inline Value Object::getProperty(Runtime& runtime, const char* name) const { return getProperty(runtime, String::createFromAscii(runtime, name)); } inline Value Object::getProperty(Runtime& runtime, const String& name) const { return runtime.getProperty(*this, name); } inline Value Object::getProperty(Runtime& runtime, const PropNameID& name) const { return runtime.getProperty(*this, name); } inline bool Object::hasProperty(Runtime& runtime, const char* name) const { return hasProperty(runtime, String::createFromAscii(runtime, name)); } inline bool Object::hasProperty(Runtime& runtime, const String& name) const { return runtime.hasProperty(*this, name); } inline bool Object::hasProperty(Runtime& runtime, const PropNameID& name) const { return runtime.hasProperty(*this, name); } template void Object::setProperty(Runtime& runtime, const char* name, T&& value) { setProperty( runtime, String::createFromAscii(runtime, name), std::forward(value)); } template void Object::setProperty(Runtime& runtime, const String& name, T&& value) { setPropertyValue( runtime, name, detail::toValue(runtime, std::forward(value))); } template void Object::setProperty(Runtime& runtime, const PropNameID& name, T&& value) { setPropertyValue( runtime, name, detail::toValue(runtime, std::forward(value))); } inline Array Object::getArray(Runtime& runtime) const& { assert(runtime.isArray(*this)); (void)runtime; // when assert is disabled we need to mark this as used return Array(runtime.cloneObject(ptr_)); } inline Array Object::getArray(Runtime& runtime) && { assert(runtime.isArray(*this)); (void)runtime; // when assert is disabled we need to mark this as used Runtime::PointerValue* value = ptr_; ptr_ = nullptr; return Array(value); } inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) const& { assert(runtime.isArrayBuffer(*this)); (void)runtime; // when assert is disabled we need to mark this as used return ArrayBuffer(runtime.cloneObject(ptr_)); } inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && { assert(runtime.isArrayBuffer(*this)); (void)runtime; // when assert is disabled we need to mark this as used Runtime::PointerValue* value = ptr_; ptr_ = nullptr; return ArrayBuffer(value); } inline Function Object::getFunction(Runtime& runtime) const& { assert(runtime.isFunction(*this)); return Function(runtime.cloneObject(ptr_)); } inline Function Object::getFunction(Runtime& runtime) && { assert(runtime.isFunction(*this)); (void)runtime; // when assert is disabled we need to mark this as used Runtime::PointerValue* value = ptr_; ptr_ = nullptr; return Function(value); } template inline bool Object::isHostObject(Runtime& runtime) const { return runtime.isHostObject(*this) && std::dynamic_pointer_cast(runtime.getHostObject(*this)); } template <> inline bool Object::isHostObject(Runtime& runtime) const { return runtime.isHostObject(*this); } template inline std::shared_ptr Object::getHostObject(Runtime& runtime) const { assert(isHostObject(runtime)); return std::static_pointer_cast(runtime.getHostObject(*this)); } template inline std::shared_ptr Object::asHostObject(Runtime& runtime) const { if (!isHostObject(runtime)) { detail::throwJSError(runtime, "Object is not a HostObject of desired type"); } return std::static_pointer_cast(runtime.getHostObject(*this)); } template <> inline std::shared_ptr Object::getHostObject( Runtime& runtime) const { assert(runtime.isHostObject(*this)); return runtime.getHostObject(*this); } inline Array Object::getPropertyNames(Runtime& runtime) const { return runtime.getPropertyNames(*this); } inline Value WeakObject::lock(Runtime& runtime) { return runtime.lockWeakObject(*this); } template void Array::setValueAtIndex(Runtime& runtime, size_t i, T&& value) { setValueAtIndexImpl( runtime, i, detail::toValue(runtime, std::forward(value))); } inline Value Array::getValueAtIndex(Runtime& runtime, size_t i) const { return runtime.getValueAtIndex(*this, i); } inline Function Function::createFromHostFunction( Runtime& runtime, const jsi::PropNameID& name, unsigned int paramCount, jsi::HostFunctionType func) { return runtime.createFunctionFromHostFunction( name, paramCount, std::move(func)); } inline Value Function::call(Runtime& runtime, const Value* args, size_t count) const { return runtime.call(*this, Value::undefined(), args, count); } inline Value Function::call(Runtime& runtime, std::initializer_list args) const { return call(runtime, args.begin(), args.size()); } template inline Value Function::call(Runtime& runtime, Args&&... args) const { // A more awesome version of this would be able to create raw values // which can be used directly without wrapping and unwrapping, but // this will do for now. return call(runtime, {detail::toValue(runtime, std::forward(args))...}); } inline Value Function::callWithThis( Runtime& runtime, const Object& jsThis, const Value* args, size_t count) const { return runtime.call(*this, Value(runtime, jsThis), args, count); } inline Value Function::callWithThis( Runtime& runtime, const Object& jsThis, std::initializer_list args) const { return callWithThis(runtime, jsThis, args.begin(), args.size()); } template inline Value Function::callWithThis( Runtime& runtime, const Object& jsThis, Args&&... args) const { // A more awesome version of this would be able to create raw values // which can be used directly without wrapping and unwrapping, but // this will do for now. return callWithThis( runtime, jsThis, {detail::toValue(runtime, std::forward(args))...}); } template inline Array Array::createWithElements(Runtime& runtime, Args&&... args) { return createWithElements( runtime, {detail::toValue(runtime, std::forward(args))...}); } template inline std::vector PropNameID::names( Runtime& runtime, Args&&... args) { return names({detail::toPropNameID(runtime, std::forward(args))...}); } template inline std::vector PropNameID::names( PropNameID(&&propertyNames)[N]) { std::vector result; result.reserve(N); for (auto& name : propertyNames) { result.push_back(std::move(name)); } return result; } inline Value Function::callAsConstructor( Runtime& runtime, const Value* args, size_t count) const { return runtime.callAsConstructor(*this, args, count); } inline Value Function::callAsConstructor( Runtime& runtime, std::initializer_list args) const { return callAsConstructor(runtime, args.begin(), args.size()); } template inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args) const { return callAsConstructor( runtime, {detail::toValue(runtime, std::forward(args))...}); } } // namespace jsi } // namespace facebook