From d0a66fdaaa3aa6e3f70aaadcc92c681ade6eabfe Mon Sep 17 00:00:00 2001 From: FFranck Date: Mon, 22 Nov 2021 13:16:46 +0100 Subject: [PATCH] Rename namespaces in the JSI codebase to reflect that it doesn't just support Hermes (#4079) Rework the namespace names in our Hermes/JSI layer to more accurately reflect that we support JSI, and to remove ambiguities and namespace clashes. This closes RJS-1337. --- CHANGELOG.md | 2 +- RealmJS.podspec | 2 +- react-native/ios/RealmReact/RealmReact.mm | 6 +- scripts/build-ios.sh | 2 +- src/CMakeLists.txt | 4 +- .../io_realm_react_RealmReactModule.cpp | 6 +- src/hermes/hermes_return_value.hpp | 172 --------------- src/{hermes => jsi}/CMakeLists.txt | 2 +- .../hermes_class.hpp => jsi/jsi_class.hpp} | 198 +++++++++--------- .../jsi_function.hpp} | 17 +- .../hermes_init.cpp => jsi/jsi_init.cpp} | 21 +- src/{hermes/hermes_init.h => jsi/jsi_init.h} | 4 +- .../hermes_init.hpp => jsi/jsi_init.hpp} | 14 +- .../hermes_object.hpp => jsi/jsi_object.hpp} | 84 ++++---- .../jsi_protected.hpp} | 2 +- src/jsi/jsi_return_value.hpp | 118 +++++++++++ .../hermes_string.hpp => jsi/jsi_string.hpp} | 18 +- .../hermes_types.hpp => jsi/jsi_types.hpp} | 101 ++++----- .../hermes_value.hpp => jsi/jsi_value.hpp} | 94 +++++---- 19 files changed, 421 insertions(+), 446 deletions(-) delete mode 100644 src/hermes/hermes_return_value.hpp rename src/{hermes => jsi}/CMakeLists.txt (93%) rename src/{hermes/hermes_class.hpp => jsi/jsi_class.hpp} (76%) rename src/{hermes/hermes_function.hpp => jsi/jsi_function.hpp} (62%) rename src/{hermes/hermes_init.cpp => jsi/jsi_init.cpp} (69%) rename src/{hermes/hermes_init.h => jsi/jsi_init.h} (89%) rename src/{hermes/hermes_init.hpp => jsi/jsi_init.hpp} (80%) rename src/{hermes/hermes_object.hpp => jsi/jsi_object.hpp} (54%) rename src/{hermes/hermes_protected.hpp => jsi/jsi_protected.hpp} (98%) create mode 100644 src/jsi/jsi_return_value.hpp rename src/{hermes/hermes_string.hpp => jsi/jsi_string.hpp} (75%) rename src/{hermes/hermes_types.hpp => jsi/jsi_types.hpp} (69%) rename src/{hermes/hermes_value.hpp => jsi/jsi_value.hpp} (69%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1276fd57e5..e56c4fb779 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ NOTE: This is an early (alpha) release with Hermes/JSI support: We expect crashe * File format: generates Realms with format v22 (reads and upgrades file format v5 or later for non-synced Realm, upgrades file format v10 or later for synced Realms). ### Internal -* None. +* Restructured C++ namespaces and files to reflect that we support JSI, not just Hermes. 10.20.0-alpha.1 Release notes (2021-9-22) ============================================================= diff --git a/RealmJS.podspec b/RealmJS.podspec index 03cbb3e2cf..96f9f15f70 100644 --- a/RealmJS.podspec +++ b/RealmJS.podspec @@ -58,7 +58,7 @@ Pod::Spec.new do |s| 'HEADER_SEARCH_PATHS' => [ '"$(PODS_TARGET_SRCROOT)/react-native/ios/RealmReact/"', '"$(PODS_TARGET_SRCROOT)/src/"', - '"$(PODS_TARGET_SRCROOT)/src/hermes/"', + '"$(PODS_TARGET_SRCROOT)/src/jsi/"', '"$(PODS_ROOT)/Headers/Public/React-Core/"' #"'#{app_path}/ios/Pods/Headers/Public/React-Core'" # Use this line instead of 👆 while linting ].join(' ') diff --git a/react-native/ios/RealmReact/RealmReact.mm b/react-native/ios/RealmReact/RealmReact.mm index 198c09801b..17a589fb6a 100644 --- a/react-native/ios/RealmReact/RealmReact.mm +++ b/react-native/ios/RealmReact/RealmReact.mm @@ -19,7 +19,7 @@ #import "RealmReact.h" #import "RealmAnalytics.h" -#import +#import #import #import @@ -94,7 +94,7 @@ - (void)removeListenerForEvent:(NSString *)eventName handler:(RealmReactEventHan } - (void)invalidate { - realm_hermes_invalidate_caches(); + realm_jsi_invalidate_caches(); } - (void)dealloc { @@ -130,7 +130,7 @@ - (void)setBridge:(RCTBridge *)bridge { auto& rt = *static_cast(bridge.runtime); auto exports = jsi::Object(rt); - realm_hermes_init(rt, exports); + realm_jsi_init(rt, exports); } queue:RCTJSThread]; } } diff --git a/scripts/build-ios.sh b/scripts/build-ios.sh index 53e6145791..07526bc6f9 100755 --- a/scripts/build-ios.sh +++ b/scripts/build-ios.sh @@ -108,7 +108,7 @@ done rm -rf _include mkdir -p _include/realm-js-ios -cp "$PROJECT_ROOT"/src/hermes/hermes_init.h _include/realm-js-ios/ +cp "$PROJECT_ROOT"/src/jsi/jsi_init.h _include/realm-js-ios/ rm -rf ../realm-js-ios.xcframework xcodebuild -create-xcframework \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 582fa4761d..7035e6263f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,9 +7,9 @@ target_include_directories(realm-js-shared PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) if(DEFINED CMAKE_JS_VERSION) add_subdirectory(node) elseif(ANDROID) - add_subdirectory(hermes) + add_subdirectory(jsi) add_subdirectory(android) elseif(CMAKE_SYSTEM_NAME STREQUAL iOS) - add_subdirectory(hermes) + add_subdirectory(jsi) add_subdirectory(ios) endif() diff --git a/src/android/io_realm_react_RealmReactModule.cpp b/src/android/io_realm_react_RealmReactModule.cpp index 03ff4c8ac4..01617d32e1 100644 --- a/src/android/io_realm_react_RealmReactModule.cpp +++ b/src/android/io_realm_react_RealmReactModule.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include "platform.hpp" #include "jni_utils.hpp" #include "hack.hpp" @@ -101,12 +101,12 @@ JNIEXPORT void JNICALL Java_io_realm_react_RealmReactModule_install(JNIEnv*, jcl __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "Building an exports object"); auto exports = jsi::Object(*runtime); __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "Initializing ..."); - realm_hermes_init(*runtime, exports); + realm_jsi_init(*runtime, exports); } } JNIEXPORT void JNICALL Java_io_realm_react_RealmReactModule_invalidateCaches(JNIEnv*, jclass) { __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "invalidateCaches"); - realm_hermes_invalidate_caches(); + realm_jsi_invalidate_caches(); } diff --git a/src/hermes/hermes_return_value.hpp b/src/hermes/hermes_return_value.hpp deleted file mode 100644 index 667f8c5ce2..0000000000 --- a/src/hermes/hermes_return_value.hpp +++ /dev/null @@ -1,172 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2021 Realm Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "hermes_types.hpp" -#include "hermes_string.hpp" - -namespace realm { -namespace js { - -template <> -class ReturnValue { - JsiEnv m_env; - jsi::Value m_value; // defaults to undefined - -public: - ReturnValue(JsiEnv env) - : m_env(env) - { - } - ReturnValue(JsiEnv env, jsi::Value&& value) - : m_env(env) - , m_value(std::move(value)) - { - } - ReturnValue(JsiEnv env, const jsi::Value& value) - : m_env(env) - , m_value(env, value) - { - } - - jsi::Value ToValue() && - { - return std::move(m_value); - } - - void set(JsiVal value) - { - m_value = std::move(value.get()); - } - void set(const jsi::Value& value) - { - m_value = jsi::Value(m_env, value); - } - void set(jsi::Value&& value) - { - m_value = std::move(value); - } - - void set(const std::string& string) - { - m_value = str(m_env, string).get(); - } - - void set(const char* c_str) - { - if (!c_str) { - set_null(); - } - - void set(JsiVal value) - { - m_value = std::move(value.get()); - } - - void set(const std::string& string) - { - m_value = str(m_env, string).get(); - } - - void set(const char* c_str) - { - if (!c_str) { - set_null(); - } - else { - m_value = str(m_env, c_str).get(); - } - } - - void set(bool boolean) - { - m_value = jsi::Value(boolean); - } - - void set(double number) - { - m_value = jsi::Value(number); - } - - void set(int32_t number) - { - set(double(number)); - } - - void set(uint32_t number) - { - set(double(number)); - } - - void set(realm::Mixed mixed) - { - m_value = Value::from_mixed(m_env, nullptr, mixed).get(); - } - } - - void set(bool boolean) - { - m_value = jsi::Value(boolean); - } - - void set(double number) - { - m_value = jsi::Value(number); - } - - void set(int32_t number) - { - set(double(number)); - } - - void set(uint32_t number) - { - set(double(number)); - } - - void set(realm::Mixed mixed) - { - m_value = jsi::Value(m_env, TypeMixed::get_instance().wrap(m_env, mixed)); - } - - void set_null() - { - m_value = jsi::Value::null(); - } - - - void set_undefined() - { - m_value = jsi::Value::undefined(); - } - - template - void set(util::Optional value) - { - if (value) { - set(std::move(*value)); - } - else { - set_undefined(); - } - } -}; - -} // namespace js -} // namespace realm diff --git a/src/hermes/CMakeLists.txt b/src/jsi/CMakeLists.txt similarity index 93% rename from src/hermes/CMakeLists.txt rename to src/jsi/CMakeLists.txt index 35df2f2159..12294d5f78 100644 --- a/src/hermes/CMakeLists.txt +++ b/src/jsi/CMakeLists.txt @@ -2,7 +2,7 @@ set(REACT_NATIVE_ROOT_DIR "${PACKAGE_ROOT_DIR}/node_modules/react-native") set(JSI_HEADER_DIR "${REACT_NATIVE_ROOT_DIR}/ReactCommon/jsi") add_library(realm-js-hermes OBJECT - hermes_init.cpp + jsi_init.cpp ) target_include_directories(realm-js-hermes PRIVATE ${JSI_HEADER_DIR}) diff --git a/src/hermes/hermes_class.hpp b/src/jsi/jsi_class.hpp similarity index 76% rename from src/hermes/hermes_class.hpp rename to src/jsi/jsi_class.hpp index 3d7cecc203..9de70254d2 100644 --- a/src/hermes/hermes_class.hpp +++ b/src/jsi/jsi_class.hpp @@ -17,11 +17,10 @@ //////////////////////////////////////////////////////////////////////////// #pragma once - -#include "hermes_types.hpp" -#include "hermes_return_value.hpp" -#include "hermes_string.hpp" -#include "hermes_object.hpp" +#include "jsi_types.hpp" +#include "jsi_return_value.hpp" +#include "jsi_string.hpp" +#include "jsi_object.hpp" #include "js_class.hpp" #include "js_util.hpp" @@ -41,13 +40,15 @@ struct RealmObjectClass; template class RealmClass; +namespace fbjsi = facebook::jsi; + template <> -struct Arguments { +struct Arguments { const std::vector valStorage; const JsiEnv ctx; const size_t count; const JsiVal* const value; - Arguments(JsiEnv env, size_t argc, const jsi::Value* argv) + Arguments(JsiEnv env, size_t argc, const fbjsi::Value* argv) : valStorage([&] { std::vector out; out.reserve(argc); @@ -98,10 +99,10 @@ struct Arguments { } }; -namespace hermes { +namespace realmjsi { // realm::js::realmjsi -inline std::optional ObjectGetOwnPropertyDescriptor(JsiEnv env, const jsi::Object& target, - const std::string& name) +inline std::optional ObjectGetOwnPropertyDescriptor(JsiEnv env, const fbjsi::Object& target, + const std::string& name) { auto obj = js::globalType(env, "Object"); auto res = obj.getPropertyAsFunction(env, "getOwnPropertyDescriptor").callWithThis(env, obj, target, name); @@ -110,20 +111,20 @@ inline std::optional ObjectGetOwnPropertyDescriptor(JsiEnv env, con return std::move(res).getObject(env); } -inline void ObjectSetPrototypeOf(JsiEnv env, const jsi::Value& target, const jsi::Value& proto) +inline void ObjectSetPrototypeOf(JsiEnv env, const fbjsi::Value& target, const fbjsi::Value& proto) { auto obj = js::globalType(env, "Object"); obj.getPropertyAsFunction(env, "setPrototypeOf").callWithThis(env, obj, target, proto); } -inline void defineProperty(JsiEnv env, const jsi::Object& target, StringData name, const jsi::Object& descriptor) +inline void defineProperty(JsiEnv env, const fbjsi::Object& target, StringData name, const fbjsi::Object& descriptor) { auto objClass = js::globalType(env, "Object"); objClass.getPropertyAsFunction(env, "defineProperty") .callWithThis(env, objClass, target, str(env, name), descriptor); }; -inline void copyProperty(JsiEnv env, const jsi::Object& from, const jsi::Object& to, const std::string& name) +inline void copyProperty(JsiEnv env, const fbjsi::Object& from, const fbjsi::Object& to, const std::string& name) { auto prop = ObjectGetOwnPropertyDescriptor(env, from, name); REALM_ASSERT_RELEASE(prop); @@ -133,18 +134,18 @@ inline void copyProperty(JsiEnv env, const jsi::Object& from, const jsi::Object& inline constexpr const char g_internal_field[] = "__Realm_internal"; template -using ClassDefinition = js::ClassDefinition; +using ClassDefinition = js::ClassDefinition; -using ConstructorType = js::ConstructorType; -using ArgumentsMethodType = js::ArgumentsMethodType; -using ReturnValue = js::ReturnValue; -using Arguments = js::Arguments; -using PropertyType = js::PropertyType; -using IndexPropertyType = js::IndexPropertyType; -using StringPropertyType = js::StringPropertyType; +using ConstructorType = js::ConstructorType; +using ArgumentsMethodType = js::ArgumentsMethodType; +using ReturnValue = js::ReturnValue; +using Arguments = js::Arguments; +using PropertyType = js::PropertyType; +using IndexPropertyType = js::IndexPropertyType; +using StringPropertyType = js::StringPropertyType; template -class Wrapper : public jsi::HostObject { +class Wrapper : public fbjsi::HostObject { public: template >> Wrapper(Args&&... args) @@ -168,13 +169,13 @@ inline T& unwrap(const std::shared_ptr>& wrapper) } template -inline T& unwrap(JsiEnv env, const jsi::Object& wrapper) +inline T& unwrap(JsiEnv env, const fbjsi::Object& wrapper) { return unwrap(wrapper.getHostObject>(env)); } template -inline T& unwrap(JsiEnv env, const jsi::Value& wrapper) +inline T& unwrap(JsiEnv env, const fbjsi::Value& wrapper) { return unwrap(env, wrapper.asObject(env)); } @@ -200,13 +201,13 @@ inline T* unwrapUnique(JsiEnv env, const U& arg) template JsiObj wrap(JsiEnv env, T arg) { - return env(jsi::Object::createFromHostObject(env, std::make_shared>(std::move(arg)))); + return env(fbjsi::Object::createFromHostObject(env, std::make_shared>(std::move(arg)))); } template >> JsiObj wrap(JsiEnv env, Args&&... args) { - return env(jsi::Object::createFromHostObject(env, std::make_shared>(std::forward(args)...))); + return env(fbjsi::Object::createFromHostObject(env, std::make_shared>(std::forward(args)...))); } template @@ -229,19 +230,19 @@ class ObjectWrap { { auto& s_type = get_class(); - auto nativeFunc = - !bool(s_type.constructor) - ? jsi::Value() - : jsi::Function::createFromHostFunction( - env, propName(env, s_type.name), /* XXX paramCount */ 0, - [](jsi::Runtime& rt, const jsi::Value&, const jsi::Value* args, size_t count) -> jsi::Value { - REALM_ASSERT_RELEASE(count >= 1); - auto env = JsiEnv(rt); - auto& s_type = get_class(); - auto arguments = Arguments{env, count - 1, args + 1}; - s_type.constructor(env, env(args[0]).asObject(), arguments); - return jsi::Value(); - }); + auto nativeFunc = !bool(s_type.constructor) + ? fbjsi::Value() + : fbjsi::Function::createFromHostFunction( + env, propName(env, s_type.name), /* XXX paramCount */ 0, + [](fbjsi::Runtime& rt, const fbjsi::Value&, const fbjsi::Value* args, + size_t count) -> fbjsi::Value { + REALM_ASSERT_RELEASE(count >= 1); + auto env = JsiEnv(rt); + auto& s_type = get_class(); + auto arguments = Arguments{env, count - 1, args + 1}; + s_type.constructor(env, env(args[0]).asObject(), arguments); + return fbjsi::Value(); + }); s_ctor = env(globalType(env, "Function") .call(env, "nativeFunc", @@ -266,14 +267,14 @@ class ObjectWrap { .asObject(env) .asFunction(env)); - js::Context::register_invalidator([] { + js::Context::register_invalidator([] { // Ensure the static constructor is destructed when the runtime goes away. // This is to avoid the reassignment of s_ctor throwing because the runtime has disappeared. s_ctor.reset(); }); for (auto&& [name, prop] : s_type.static_properties) { - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); if (prop.getter) { desc.setProperty(env, "get", funcVal(env, "get_" + name, 0, prop.getter)); } @@ -284,7 +285,7 @@ class ObjectWrap { } for (auto&& [name, method] : s_type.static_methods) { - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); desc.setProperty(env, "value", funcVal(env, name, /* XXX paramCount */ 0, method)); defineProperty(env, *s_ctor, name, desc); } @@ -292,7 +293,7 @@ class ObjectWrap { auto proto = (*s_ctor)->getPropertyAsObject(env, "prototype"); for (auto&& [name, prop] : s_type.properties) { - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); if (prop.getter) { desc.setProperty(env, "get", funcVal(env, "get_" + name, 0, prop.getter)); } @@ -303,7 +304,7 @@ class ObjectWrap { } for (auto&& [name, method] : s_type.methods) { - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); desc.setProperty(env, "value", funcVal(env, name, /* XXX paramCount */ 0, method)); defineProperty(env, proto, name, desc); } @@ -317,8 +318,8 @@ class ObjectWrap { throw std::runtime_error("undefined 'prototype' on parent constructor"); } - ObjectSetPrototypeOf(env, jsi::Value(env, proto), jsi::Value(std::move(parentProto))); - ObjectSetPrototypeOf(env, jsi::Value(env, s_ctor->get()), jsi::Value(std::move(parentCtor.get()))); + ObjectSetPrototypeOf(env, fbjsi::Value(env, proto), fbjsi::Value(std::move(parentProto))); + ObjectSetPrototypeOf(env, fbjsi::Value(env, s_ctor->get()), fbjsi::Value(std::move(parentCtor.get()))); } if (s_type.index_accessor) { @@ -327,7 +328,7 @@ class ObjectWrap { // XXX Do we want to trap things like ownKeys() and getOwnPropertyDescriptors() to support for...in? auto [getter, setter] = s_type.index_accessor; - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); desc.setProperty(env, "value", globalType(env, "Function") .call(env, "getter", "setter", R"( @@ -431,33 +432,33 @@ class ObjectWrap { { auto internal = object->getProperty(env, g_internal_field); if (internal.isUndefined()) { - if constexpr (std::is_same_v>) // XXX comment why + if constexpr (std::is_same_v>) // XXX comment why return nullptr; - throw jsi::JSError(env, "no internal field"); + throw fbjsi::JSError(env, "no internal field"); } if (!JsiObj(object)->instanceOf(env, *s_ctor)) { - throw jsi::JSError(env, "calling method on wrong type of object"); + throw fbjsi::JSError(env, "calling method on wrong type of object"); } return unwrapUnique(env, std::move(internal)); } static void set_internal(JsiEnv env, const JsiObj& object, Internal* data) { - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); desc.setProperty(env, "value", wrapUnique(env, data)); desc.setProperty(env, "configurable", true); defineProperty(env, object, g_internal_field, desc); } private: - static jsi::Value funcVal(JsiEnv env, const std::string& name, size_t args, jsi::HostFunctionType&& func) + static fbjsi::Value funcVal(JsiEnv env, const std::string& name, size_t args, fbjsi::HostFunctionType&& func) { if (!func) - return jsi::Value(); - return jsi::Value( - jsi::Function::createFromHostFunction(env, propName(env, name), uint32_t(args), std::move(func))); + return fbjsi::Value(); + return fbjsi::Value( + fbjsi::Function::createFromHostFunction(env, propName(env, name), uint32_t(args), std::move(func))); }; - static void defineSchemaProperties(JsiEnv env, const jsi::Object& constructorPrototype, + static void defineSchemaProperties(JsiEnv env, const fbjsi::Object& constructorPrototype, const realm::ObjectSchema& schema, bool redefine) { // Do the same thing for all computed and persisted properties @@ -468,23 +469,23 @@ class ObjectWrap { return; } - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); desc.setProperty(env, "enumerable", true); desc.setProperty(env, "get", funcVal(env, "get_" + name, 0, - [name = String(name)](jsi::Runtime& rt, const jsi::Value& thisVal, - const jsi::Value* args, size_t count) { + [name = String(name)](fbjsi::Runtime& rt, const fbjsi::Value& thisVal, + const fbjsi::Value* args, size_t count) { if (count != 0) - throw jsi::JSError(rt, "getters take no arguments"); + throw fbjsi::JSError(rt, "getters take no arguments"); return get_class().string_accessor.getter(rt, thisVal, name); })); desc.setProperty(env, "set", funcVal(env, "set_" + name, 1, - [name = String(name)](jsi::Runtime& rt, const jsi::Value& thisVal, - const jsi::Value* args, size_t count) { + [name = String(name)](fbjsi::Runtime& rt, const fbjsi::Value& thisVal, + const fbjsi::Value* args, size_t count) { if (count != 1) - throw jsi::JSError(rt, "setters take exactly 1 argument"); + throw fbjsi::JSError(rt, "setters take exactly 1 argument"); return get_class().string_accessor.setter(rt, thisVal, name, args[0]); })); @@ -505,13 +506,13 @@ class ObjectWrap { auto& s_schemaObjectTypes = get_schemaObjectTypes(); auto& s_class = get_class(); - bool isRealmObjectClass = std::is_same_v>; + bool isRealmObjectClass = std::is_same_v>; if (!isRealmObjectClass) { - throw jsi::JSError(env, "Creating instances by schema is supported for RealmObjectClass only"); + throw fbjsi::JSError(env, "Creating instances by schema is supported for RealmObjectClass only"); } if (!internal) { - throw jsi::JSError( + throw fbjsi::JSError( env, "RealmObjectClass requires an internal realm object when creating instances by schema"); } @@ -562,7 +563,7 @@ class ObjectWrap { bool schemaExists = schemaObjects.count(schemaName); if (schemaExists) { // check if constructors have changed for the same schema object and name - if (!jsi::Function::strictEquals(env, schemaObjects.at(schemaName), constructor)) { + if (!fbjsi::Function::strictEquals(env, schemaObjects.at(schemaName), constructor)) { schemaExists = false; schemaObjects.erase(schemaName); } @@ -601,11 +602,11 @@ class ObjectWrap { const auto& schemaObjectCtor = schemaObjects.at(schemaName); auto instanceVal = schemaObjectCtor.callAsConstructor(env); if (!instanceVal.isObject()) { - throw jsi::JSError(env, "Realm object constructor must not return another value"); + throw fbjsi::JSError(env, "Realm object constructor must not return another value"); } auto instance = env(std::move(instanceVal).getObject(env)); if (!instance->instanceOf(env, schemaObjectCtor)) { - throw jsi::JSError(env, "Realm object constructor must not return another value"); + throw fbjsi::JSError(env, "Realm object constructor must not return another value"); } set_internal(env, instance, internal); @@ -622,89 +623,90 @@ class ObjectWrap { inline static auto& get_schemaObjectTypes() { // XXX this being static prevents using multiple runtimes. - static std::unordered_map> s_schemaObjectTypes; + static std::unordered_map> s_schemaObjectTypes; return s_schemaObjectTypes; } }; -} // namespace hermes +} // namespace realmjsi template -class ObjectWrap : public hermes::ObjectWrap { +class ObjectWrap : public realm::js::realmjsi::ObjectWrap { }; -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, const fbjsi::Value* args, size_t count) { auto env = JsiEnv(rt); - auto result = hermes::ReturnValue(env); - auto arguments = hermes::Arguments{env, count, args}; + auto result = realmjsi::ReturnValue(env); + auto arguments = realmjsi::Arguments{env, count, args}; F(env, env(thisVal).asObject(), arguments, result); return std::move(result).ToValue(); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, const fbjsi::Value* args, size_t count) { auto env = JsiEnv(rt); - auto result = hermes::ReturnValue(env); - auto arguments = hermes::Arguments{env, count, args}; + auto result = realmjsi::ReturnValue(env); + auto arguments = realmjsi::Arguments{env, count, args}; arguments.validate_count(0); F(env, env(thisVal).asObject(), result); return std::move(result).ToValue(); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, const fbjsi::Value* args, size_t count) { auto env = JsiEnv(rt); - auto arguments = hermes::Arguments{env, count, args}; + auto arguments = realmjsi::Arguments{env, count, args}; arguments.validate_count(1); F(env, env(thisVal).asObject(), JsiVal(env, args[0])); - return jsi::Value(); + return fbjsi::Value(); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value&, const jsi::Value* args, size_t count) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value&, const fbjsi::Value* args, size_t count) { REALM_ASSERT_RELEASE(count == 2); auto env = JsiEnv(rt); - auto out = hermes::ReturnValue(env); + auto out = realmjsi::ReturnValue(env); F(env, env(args[0]).asObject(), uint32_t(args[1].asNumber()), out); return std::move(out).ToValue(); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value&, const jsi::Value* args, size_t count) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value&, const fbjsi::Value* args, size_t count) { REALM_ASSERT_RELEASE(count == 3); auto env = JsiEnv(rt); - return jsi::Value(F(env, env(args[0]).asObject(), uint32_t(args[1].asNumber()), env(args[2]))); + return fbjsi::Value(F(env, env(args[0]).asObject(), uint32_t(args[1].asNumber()), env(args[2]))); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const hermes::String& str) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, const realmjsi::String& str) { auto env = JsiEnv(rt); - auto result = hermes::ReturnValue(env); + auto result = realmjsi::ReturnValue(env); F(env, env(thisVal).asObject(), str, result); return std::move(result).ToValue(); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const hermes::String& str, const jsi::Value& value) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, const realmjsi::String& str, + const fbjsi::Value& value) { auto env = JsiEnv(rt); F(env, env(thisVal).asObject(), str, env(value)); - return jsi::Value(); + return fbjsi::Value(); } -template -jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) +template +fbjsi::Value wrap(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, const fbjsi::Value* args, size_t count) { // This is only used in the JSC impl. REALM_UNREACHABLE(); diff --git a/src/hermes/hermes_function.hpp b/src/jsi/jsi_function.hpp similarity index 62% rename from src/hermes/hermes_function.hpp rename to src/jsi/jsi_function.hpp index e14a9dde12..cccbc4ad55 100644 --- a/src/hermes/hermes_function.hpp +++ b/src/jsi/jsi_function.hpp @@ -18,38 +18,39 @@ #pragma once -#include "hermes_types.hpp" +#include "jsi_types.hpp" namespace realm { namespace js { template <> -inline JsiVal hermes::Function::call(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) +inline JsiVal realmjsi::Function::call(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) { return env(function->call(env, env.args(arguments, argc), argc)); } template <> -inline JsiVal hermes::Function::call(JsiEnv env, const JsiFunc& function, const JsiObj& this_object, size_t argc, - const JsiVal arguments[]) +inline JsiVal realmjsi::Function::call(JsiEnv env, const JsiFunc& function, const JsiObj& this_object, size_t argc, + const JsiVal arguments[]) { return env(function->callWithThis(env, this_object, env.args(arguments, argc), argc)); } template <> -inline JsiVal hermes::Function::callback(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) +inline JsiVal realmjsi::Function::callback(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) { return env(function->call(env, env.args(arguments, argc), argc)); } template <> -inline JsiVal hermes::Function::callback(JsiEnv env, const JsiFunc& function, const JsiObj& this_object, size_t argc, - const JsiVal arguments[]) +inline JsiVal realmjsi::Function::callback(JsiEnv env, const JsiFunc& function, const JsiObj& this_object, + size_t argc, const JsiVal arguments[]) { return env(function->callWithThis(env, this_object, env.args(arguments, argc), argc)); } template <> -inline JsiObj hermes::Function::construct(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) +inline JsiObj realmjsi::Function::construct(JsiEnv env, const JsiFunc& function, size_t argc, + const JsiVal arguments[]) { return env(function->callAsConstructor(env, env.args(arguments, argc), argc).asObject(env)); } diff --git a/src/hermes/hermes_init.cpp b/src/jsi/jsi_init.cpp similarity index 69% rename from src/hermes/hermes_init.cpp rename to src/jsi/jsi_init.cpp index 254207c7b8..dd0edd7b0f 100644 --- a/src/hermes/hermes_init.cpp +++ b/src/jsi/jsi_init.cpp @@ -17,7 +17,7 @@ //////////////////////////////////////////////////////////////////////////// -#include "hermes_init.hpp" +#include "jsi_init.hpp" #if !REALM_ENABLE_SYNC #pragma comment(lib, "ws2_32.lib") @@ -29,14 +29,27 @@ #include #include -namespace realm::js::hermes { -extern "C" void realm_hermes_init(jsi::Runtime& rt, jsi::Object& exports) +namespace realmjsi = realm::js::realmjsi; +namespace fbjsi = facebook::jsi; + +namespace realm::js::jsi { +extern "C" void realm_jsi_init(fbjsi::Runtime& rt, fbjsi::Object& exports) { auto env = JsiEnv(rt); - jsi::Function realm_constructor = js::RealmClass::create_constructor(env); + fbjsi::Function realm_constructor = js::RealmClass::create_constructor(env); auto name = realm_constructor.getProperty(env, "name").asString(env); exports.setProperty(env, std::move(name), std::move(realm_constructor)); } +extern "C" void realm_jsi_invalidate_caches() +{ + // Close all cached Realms + realm::_impl::RealmCoordinator::clear_all_caches(); + // Clear the Object Store App cache, to prevent instances from using a context that was released + realm::app::App::clear_cached_apps(); + // Ensure all registered invalidators get notified that the runtime is going away. + realm::js::Context::invalidate(); +} +} extern "C" void realm_hermes_invalidate_caches() { // Close all cached Realms diff --git a/src/hermes/hermes_init.h b/src/jsi/jsi_init.h similarity index 89% rename from src/hermes/hermes_init.h rename to src/jsi/jsi_init.h index 759e56b4d7..117937f6e5 100644 --- a/src/hermes/hermes_init.h +++ b/src/jsi/jsi_init.h @@ -25,8 +25,8 @@ extern "C" { #endif namespace jsi = facebook::jsi; -void realm_hermes_init(jsi::Runtime& rt, jsi::Object& exports); -void realm_hermes_invalidate_caches(); +void realm_jsi_init(jsi::Runtime& rt, jsi::Object& exports); +void realm_jsi_invalidate_caches(); #ifdef __cplusplus } diff --git a/src/hermes/hermes_init.hpp b/src/jsi/jsi_init.hpp similarity index 80% rename from src/hermes/hermes_init.hpp rename to src/jsi/jsi_init.hpp index 79df738d4f..28e787359d 100644 --- a/src/hermes/hermes_init.hpp +++ b/src/jsi/jsi_init.hpp @@ -18,13 +18,13 @@ #pragma once -#include "hermes_string.hpp" -#include "hermes_protected.hpp" -#include "hermes_function.hpp" -#include "hermes_value.hpp" -#include "hermes_object.hpp" -#include "hermes_return_value.hpp" -#include "hermes_class.hpp" +#include "jsi_string.hpp" +#include "jsi_protected.hpp" +#include "jsi_function.hpp" +#include "jsi_value.hpp" +#include "jsi_object.hpp" +#include "jsi_return_value.hpp" +#include "jsi_class.hpp" // FIXME: js_object_accessor.hpp includes js_list.hpp which includes js_object_accessor.hpp. #include "js_object_accessor.hpp" diff --git a/src/hermes/hermes_object.hpp b/src/jsi/jsi_object.hpp similarity index 54% rename from src/hermes/hermes_object.hpp rename to src/jsi/jsi_object.hpp index c018afb5ab..3c2c414ac6 100644 --- a/src/hermes/hermes_object.hpp +++ b/src/jsi/jsi_object.hpp @@ -18,12 +18,20 @@ #pragma once -#include "hermes_types.hpp" -#include "hermes_string.hpp" +#include "jsi_types.hpp" +#include "jsi_string.hpp" namespace realm { namespace js { +namespace realmjsi { +// forward-declare JSI ObjectWrap from jsi_class.hpp +template +class ObjectWrap; +} // namespace realmjsi + +namespace fbjsi = facebook::jsi; + #if 0 inline napi_property_attributes operator|(napi_property_attributes a, PropertyAttributes b) { int flag = napi_default; @@ -46,31 +54,31 @@ inline napi_property_attributes operator|(napi_property_attributes a, PropertyAt #endif template <> -inline JsiVal hermes::Object::get_property(JsiEnv env, const JsiObj& object, StringData key) +inline JsiVal realmjsi::Object::get_property(JsiEnv env, const JsiObj& object, StringData key) { return env(object->getProperty(env, propName(env, key))); } template <> -inline JsiVal hermes::Object::get_property(JsiEnv env, const JsiObj& object, const hermes::String& key) +inline JsiVal realmjsi::Object::get_property(JsiEnv env, const JsiObj& object, const realmjsi::String& key) { return env(object->getProperty(env, propName(env, key))); } template <> -inline JsiVal hermes::Object::get_property(JsiEnv env, const JsiObj& object, uint32_t index) +inline JsiVal realmjsi::Object::get_property(JsiEnv env, const JsiObj& object, uint32_t index) { if (object->isArray(env)) return env(object->asArray(env).getValueAtIndex(env, index)); - return hermes::Object::get_property(env, object, std::to_string(index)); + return realmjsi::Object::get_property(env, object, std::to_string(index)); } template <> -inline void hermes::Object::set_property(JsiEnv env, JsiObj& object, const hermes::String& key, const JsiVal& value, - PropertyAttributes attributes) +inline void realmjsi::Object::set_property(JsiEnv env, JsiObj& object, const realmjsi::String& key, + const JsiVal& value, PropertyAttributes attributes) { if (attributes) { - auto desc = jsi::Object(env); + auto desc = fbjsi::Object(env); desc.setProperty(env, "configurable", !(attributes & DontDelete)); desc.setProperty(env, "enumerable", !(attributes & DontEnum)); desc.setProperty(env, "writable", !(attributes & ReadOnly)); @@ -86,20 +94,20 @@ inline void hermes::Object::set_property(JsiEnv env, JsiObj& object, const herme } template <> -inline void hermes::Object::set_property(JsiEnv env, JsiObj& object, uint32_t index, const JsiVal& value) +inline void realmjsi::Object::set_property(JsiEnv env, JsiObj& object, uint32_t index, const JsiVal& value) { if (object->isArray(env)) return object->asArray(env).setValueAtIndex(env, index, value); - return hermes::Object::set_property(env, object, std::to_string(index), value); + return realmjsi::Object::set_property(env, object, std::to_string(index), value); } template <> -inline std::vector hermes::Object::get_property_names(JsiEnv env, const JsiObj& object) +inline std::vector realmjsi::Object::get_property_names(JsiEnv env, const JsiObj& object) { auto namesArray = object->getPropertyNames(env); size_t count = namesArray.length(env); - std::vector names; + std::vector names; names.reserve(count); for (size_t i = 0; i < count; i++) { @@ -110,29 +118,29 @@ inline std::vector hermes::Object::get_property_names(JsiEnv env } template <> -inline JsiVal hermes::Object::get_prototype(JsiEnv env, const JsiObj& object) +inline JsiVal realmjsi::Object::get_prototype(JsiEnv env, const JsiObj& object) { auto objClass = env->global().getPropertyAsObject(env, "Object"); return env(objClass.getPropertyAsFunction(env, "getPrototypeOf").callWithThis(env, objClass, object)); } template <> -inline void hermes::Object::set_prototype(JsiEnv env, const JsiObj& object, const JsiVal& prototype) +inline void realmjsi::Object::set_prototype(JsiEnv env, const JsiObj& object, const JsiVal& prototype) { auto objClass = env->global().getPropertyAsObject(env, "Object"); objClass.getPropertyAsFunction(env, "setPrototypeOf").callWithThis(env, objClass, object, prototype); } template <> -inline JsiObj hermes::Object::create_empty(JsiEnv env) +inline JsiObj realmjsi::Object::create_empty(JsiEnv env) { return JsiObj(env); } template <> -inline JsiObj hermes::Object::create_array(JsiEnv env, uint32_t length, const JsiVal values[]) +inline JsiObj realmjsi::Object::create_array(JsiEnv env, uint32_t length, const JsiVal values[]) { - jsi::Array array = jsi::Array(env, length); + fbjsi::Array array = fbjsi::Array(env, length); for (uint32_t i = 0; i < length; i++) { array.setValueAtIndex(env, i, values[i]); } @@ -140,77 +148,77 @@ inline JsiObj hermes::Object::create_array(JsiEnv env, uint32_t length, const Js } template <> -inline JsiObj hermes::Object::create_date(JsiEnv env, double time) +inline JsiObj realmjsi::Object::create_date(JsiEnv env, double time) { return env(env->global().getPropertyAsFunction(env, "Date").callAsConstructor(env, time).asObject(env)); } template <> template -inline JsiObj hermes::Object::create_instance(JsiEnv env, typename ClassType::Internal* internal) +inline JsiObj realmjsi::Object::create_instance(JsiEnv env, typename ClassType::Internal* internal) { - return hermes::ObjectWrap::create_instance(env, internal); + return realmjsi::ObjectWrap::create_instance(env, internal); } template <> template -inline JsiObj hermes::Object::create_instance_by_schema(JsiEnv env, JsiFunc& constructor, - const realm::ObjectSchema& schema, - typename ClassType::Internal* internal) +inline JsiObj realmjsi::Object::create_instance_by_schema(JsiEnv env, JsiFunc& constructor, + const realm::ObjectSchema& schema, + typename ClassType::Internal* internal) { - return hermes::ObjectWrap::create_instance_by_schema(env, constructor, schema, internal); + return realmjsi::ObjectWrap::create_instance_by_schema(env, constructor, schema, internal); } template <> template -inline JsiObj hermes::Object::create_instance_by_schema(JsiEnv env, const realm::ObjectSchema& schema, - typename ClassType::Internal* internal) +inline JsiObj realmjsi::Object::create_instance_by_schema(JsiEnv env, const realm::ObjectSchema& schema, + typename ClassType::Internal* internal) { - return hermes::ObjectWrap::create_instance_by_schema(env, schema, internal); + return realmjsi::ObjectWrap::create_instance_by_schema(env, schema, internal); } template inline void on_context_destroy(JsiEnv env, std::string realmPath) { - hermes::ObjectWrap::on_context_destroy(env, realmPath); + realmjsi::ObjectWrap::on_context_destroy(env, realmPath); } template <> template -inline bool hermes::Object::is_instance(JsiEnv env, const JsiObj& object) +inline bool realmjsi::Object::is_instance(JsiEnv env, const JsiObj& object) { - return hermes::ObjectWrap::is_instance(env, object); + return realmjsi::ObjectWrap::is_instance(env, object); } template <> template -inline typename ClassType::Internal* hermes::Object::get_internal(JsiEnv env, const JsiObj& object) +inline typename ClassType::Internal* realmjsi::Object::get_internal(JsiEnv env, const JsiObj& object) { - return hermes::ObjectWrap::get_internal(env, object); + return realmjsi::ObjectWrap::get_internal(env, object); } template <> template -inline void hermes::Object::set_internal(JsiEnv env, const JsiObj& object, typename ClassType::Internal* internal) +inline void realmjsi::Object::set_internal(JsiEnv env, const JsiObj& object, typename ClassType::Internal* internal) { - return hermes::ObjectWrap::set_internal(env, object, internal); + return realmjsi::ObjectWrap::set_internal(env, object, internal); } template <> -inline void hermes::Object::set_global(JsiEnv env, const hermes::String& key, const JsiVal& value) +inline void realmjsi::Object::set_global(JsiEnv env, const realmjsi::String& key, const JsiVal& value) { auto global = env.global(); Object::set_property(env, global, key, value); } template <> -inline JsiVal hermes::Object::get_global(JsiEnv env, const hermes::String& key) +inline JsiVal realmjsi::Object::get_global(JsiEnv env, const realmjsi::String& key) { return Object::get_property(env, env.global(), key); } template <> -inline JsiVal hermes::Exception::value(JsiEnv env, const std::string& message) +inline JsiVal realmjsi::Exception::value(JsiEnv env, const std::string& message) { return str(env, message); } diff --git a/src/hermes/hermes_protected.hpp b/src/jsi/jsi_protected.hpp similarity index 98% rename from src/hermes/hermes_protected.hpp rename to src/jsi/jsi_protected.hpp index 6b9cc01f1a..255e35ab3f 100644 --- a/src/hermes/hermes_protected.hpp +++ b/src/jsi/jsi_protected.hpp @@ -18,7 +18,7 @@ #pragma once -#include "hermes_types.hpp" +#include "jsi_types.hpp" namespace realm { namespace js { diff --git a/src/jsi/jsi_return_value.hpp b/src/jsi/jsi_return_value.hpp new file mode 100644 index 0000000000..7d6c19bf3f --- /dev/null +++ b/src/jsi/jsi_return_value.hpp @@ -0,0 +1,118 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "jsi_types.hpp" +#include "jsi_string.hpp" + +namespace realm { +namespace js { + +namespace fbjsi = facebook::jsi; + +template <> +class ReturnValue { + JsiEnv m_env; + fbjsi::Value m_value; // defaults to undefined + +public: + ReturnValue(JsiEnv env) + : m_env(env) + { + } + ReturnValue(JsiEnv env, fbjsi::Value&& value) + : m_env(env) + , m_value(std::move(value)) + { + } + ReturnValue(JsiEnv env, const fbjsi::Value& value) + : m_env(env) + , m_value(env, value) + { + } + + fbjsi::Value ToValue() && + { + return std::move(m_value); + } + + void set(JsiVal value) + { + m_value = std::move(value.get()); + } + + void set(const std::string& string) + { + m_value = str(m_env, string).get(); + } + + void set(const char* c_str) + { + if (!c_str) { + set_null(); + } + else { + m_value = str(m_env, c_str).get(); + } + } + + void set(bool boolean) + { + m_value = fbjsi::Value(boolean); + } + + void set(double number) + { + m_value = fbjsi::Value(number); + } + + void set(int32_t number) + { + set(double(number)); + } + + void set(uint32_t number) + { + set(double(number)); + } + + void set(realm::Mixed mixed) + { + m_value = js::Value::from_mixed(m_env, nullptr, mixed).get(); + } + + void set_null() + { + m_value = fbjsi::Value::null(); + } + + + void set_undefined() + { + m_value = fbjsi::Value::undefined(); + } + else + { + set_undefined(); + } +} +}; + +} // namespace js +} // namespace realm diff --git a/src/hermes/hermes_string.hpp b/src/jsi/jsi_string.hpp similarity index 75% rename from src/hermes/hermes_string.hpp rename to src/jsi/jsi_string.hpp index 1a78e2d8c2..fa5763b438 100644 --- a/src/hermes/hermes_string.hpp +++ b/src/jsi/jsi_string.hpp @@ -18,14 +18,16 @@ #pragma once -#include "hermes_types.hpp" +#include "jsi_types.hpp" namespace realm { namespace js { +namespace fbjsi = facebook::jsi; + template <> -class String { - using StringType = String; +class String { + using StringType = String; std::string m_str; @@ -71,20 +73,20 @@ class String { return m_str; } - jsi::String ToString(jsi::Runtime* env) + fbjsi::String ToString(fbjsi::Runtime* env) { - return jsi::String::createFromUtf8(*env, m_str); + return fbjsi::String::createFromUtf8(*env, m_str); } }; -inline jsi::PropNameID propName(JsiEnv env, StringData name) +inline fbjsi::PropNameID propName(JsiEnv env, StringData name) { - return jsi::PropNameID::forUtf8(env, reinterpret_cast(name.data()), name.size()); + return fbjsi::PropNameID::forUtf8(env, reinterpret_cast(name.data()), name.size()); } inline JsiString str(JsiEnv env, StringData name) { - return env(jsi::String::createFromUtf8(env, reinterpret_cast(name.data()), name.size())); + return env(fbjsi::String::createFromUtf8(env, reinterpret_cast(name.data()), name.size())); } } // namespace js diff --git a/src/hermes/hermes_types.hpp b/src/jsi/jsi_types.hpp similarity index 69% rename from src/hermes/hermes_types.hpp rename to src/jsi/jsi_types.hpp index 21d00fe246..a739100bbc 100644 --- a/src/hermes/hermes_types.hpp +++ b/src/jsi/jsi_types.hpp @@ -32,7 +32,7 @@ namespace realm { -namespace jsi = facebook::jsi; +namespace fbjsi = facebook::jsi; namespace js { class JsiVal; @@ -42,32 +42,32 @@ class JsiFunc; class JsiEnv { public: - /*implicit*/ JsiEnv(jsi::Runtime& rt) + /*implicit*/ JsiEnv(fbjsi::Runtime& rt) : m_rt(&rt) { } - /*implicit*/ operator jsi::Runtime&() const + /*implicit*/ operator fbjsi::Runtime&() const { return *m_rt; } - jsi::Runtime* operator->() const + fbjsi::Runtime* operator->() const { return m_rt; } - jsi::Runtime& get() const + fbjsi::Runtime& get() const { return *m_rt; } - JsiVal operator()(const jsi::Value&) const; - JsiVal operator()(jsi::Value&&) const; - JsiObj operator()(const jsi::Object&) const; - JsiObj operator()(jsi::Object&&) const; - JsiString operator()(const jsi::String&) const; - JsiString operator()(jsi::String&&) const; - JsiFunc operator()(const jsi::Function&) const; - JsiFunc operator()(jsi::Function&&) const; + JsiVal operator()(const fbjsi::Value&) const; + JsiVal operator()(fbjsi::Value&&) const; + JsiObj operator()(const fbjsi::Object&) const; + JsiObj operator()(fbjsi::Object&&) const; + JsiString operator()(const fbjsi::String&) const; + JsiString operator()(fbjsi::String&&) const; + JsiFunc operator()(const fbjsi::Function&) const; + JsiFunc operator()(fbjsi::Function&&) const; JsiVal null() const; JsiVal undefined() const; @@ -75,7 +75,7 @@ class JsiEnv { JsiObj global() const; /** Warning, this can only appear directly as an argument to callFoo(), not assigned to a variable! */ - const jsi::Value* args(const JsiVal* argv, size_t argc, std::vector&& buf = {}) const; + const fbjsi::Value* args(const JsiVal* argv, size_t argc, std::vector&& buf = {}) const; friend bool operator==(const JsiEnv& a, const JsiEnv& b) { @@ -86,7 +86,7 @@ class JsiEnv { JsiObj obj(std::pair... pairs); private: - jsi::Runtime* m_rt; + fbjsi::Runtime* m_rt; }; template @@ -161,29 +161,29 @@ class JsiWrap { T m_val; }; -class JsiString : public JsiWrap { +class JsiString : public JsiWrap { public: using JsiWrap::JsiWrap; - JsiString(JsiEnv env, const jsi::String& val) - : JsiWrap(env, jsi::Value(env, val).getString(env)) + JsiString(JsiEnv env, const fbjsi::String& val) + : JsiWrap(env, fbjsi::Value(env, val).getString(env)) { } }; -class JsiFunc : public JsiWrap { +class JsiFunc : public JsiWrap { public: using JsiWrap::JsiWrap; - JsiFunc(JsiEnv env, const jsi::Function& val) - : JsiWrap(env, jsi::Value(env, val).getObject(env).getFunction(env)) + JsiFunc(JsiEnv env, const fbjsi::Function& val) + : JsiWrap(env, fbjsi::Value(env, val).getObject(env).getFunction(env)) { } }; -class JsiObj : public JsiWrap { +class JsiObj : public JsiWrap { public: using JsiWrap::JsiWrap; - JsiObj(JsiEnv env, const jsi::Object& val) - : JsiWrap(env, jsi::Value(env, val).getObject(env)) + JsiObj(JsiEnv env, const fbjsi::Object& val) + : JsiWrap(env, fbjsi::Value(env, val).getObject(env)) { } /*implicit*/ JsiObj(JsiFunc f) @@ -191,16 +191,16 @@ class JsiObj : public JsiWrap { { } explicit JsiObj(JsiEnv env) - : JsiWrap(env, jsi::Object(env)) + : JsiWrap(env, fbjsi::Object(env)) { } }; -class JsiVal : public JsiWrap { +class JsiVal : public JsiWrap { public: using JsiWrap::JsiWrap; - JsiVal(JsiEnv env, const jsi::Value& val) - : JsiWrap(env, jsi::Value(env, val)) + JsiVal(JsiEnv env, const fbjsi::Value& val) + : JsiWrap(env, fbjsi::Value(env, val)) { } /*implicit*/ JsiVal(JsiString val) @@ -226,52 +226,52 @@ class JsiVal : public JsiWrap { } }; -inline JsiVal JsiEnv::operator()(const jsi::Value& val) const +inline JsiVal JsiEnv::operator()(const fbjsi::Value& val) const { return {*this, val}; } -inline JsiVal JsiEnv::operator()(jsi::Value&& val) const +inline JsiVal JsiEnv::operator()(fbjsi::Value&& val) const { return {*this, std::move(val)}; } -inline JsiObj JsiEnv::operator()(const jsi::Object& val) const +inline JsiObj JsiEnv::operator()(const fbjsi::Object& val) const { return {*this, val}; } -inline JsiObj JsiEnv::operator()(jsi::Object&& val) const +inline JsiObj JsiEnv::operator()(fbjsi::Object&& val) const { return {*this, std::move(val)}; } -inline JsiString JsiEnv::operator()(const jsi::String& val) const +inline JsiString JsiEnv::operator()(const fbjsi::String& val) const { return {*this, val}; } -inline JsiString JsiEnv::operator()(jsi::String&& val) const +inline JsiString JsiEnv::operator()(fbjsi::String&& val) const { return {*this, std::move(val)}; } -inline JsiFunc JsiEnv::operator()(const jsi::Function& val) const +inline JsiFunc JsiEnv::operator()(const fbjsi::Function& val) const { return {*this, val}; } -inline JsiFunc JsiEnv::operator()(jsi::Function&& val) const +inline JsiFunc JsiEnv::operator()(fbjsi::Function&& val) const { return {*this, std::move(val)}; } inline JsiVal JsiEnv::null() const { - return {*this, jsi::Value::null()}; + return {*this, fbjsi::Value::null()}; } inline JsiVal JsiEnv::undefined() const { - return {*this, jsi::Value::undefined()}; + return {*this, fbjsi::Value::undefined()}; } inline JsiObj JsiEnv::global() const { return {*this, m_rt->global()}; } -inline const jsi::Value* JsiEnv::args(const JsiVal* argv, size_t argc, std::vector&& buf) const +inline const fbjsi::Value* JsiEnv::args(const JsiVal* argv, size_t argc, std::vector&& buf) const { // Special case for 0 or 1 arguments to avoid any copies and allocations. if (argc == 0) @@ -290,12 +290,12 @@ inline const jsi::Value* JsiEnv::args(const JsiVal* argv, size_t argc, std::vect template JsiObj JsiEnv::obj(std::pair... pairs) { - auto obj = jsi::Object(*this); + auto obj = fbjsi::Object(*this); (..., obj.setProperty(*this, pairs.first, std::move(pairs.second))); return (*this)(std::move(obj)); } -namespace hermes { +namespace realmjsi { struct Types { using Context = JsiEnv; using GlobalContext = JsiEnv; @@ -304,8 +304,8 @@ struct Types { using String = JsiString; using Function = JsiFunc; - using JsiFunctionCallback = jsi::Value (*)(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, - size_t count); + using JsiFunctionCallback = fbjsi::Value (*)(fbjsi::Runtime& rt, const fbjsi::Value& thisVal, + const fbjsi::Value* args, size_t count); using JsiIndexGetterCallback = JsiFunctionCallback; using JsiIndexSetterCallback = JsiFunctionCallback; @@ -323,11 +323,12 @@ struct Types { using IndexPropertyGetterCallback = JsiIndexGetterCallback; using IndexPropertySetterCallback = JsiIndexSetterCallback; - using StringPropertyGetterCallback = jsi::Value (*)(jsi::Runtime&, const jsi::Value&, const js::String&); - using StringPropertySetterCallback = jsi::Value (*)(jsi::Runtime&, const jsi::Value&, const js::String&, - const jsi::Value&); + using StringPropertyGetterCallback = fbjsi::Value (*)(fbjsi::Runtime&, const fbjsi::Value&, + const js::String&); + using StringPropertySetterCallback = fbjsi::Value (*)(fbjsi::Runtime&, const fbjsi::Value&, + const js::String&, const fbjsi::Value&); using StringPropertyEnumeratorCallback = JsiStringPropertyEnumeratorCallback; -}; +}; // struct Types template class ObjectWrap; @@ -340,16 +341,16 @@ using Object = js::Object; using Exception = js::Exception; using ReturnValue = js::ReturnValue; -} // namespace hermes +} // namespace realmjsi template <> -inline hermes::Types::Context hermes::Context::get_global_context(hermes::Types::Context env) +inline realmjsi::Types::Context realmjsi::Context::get_global_context(realmjsi::Types::Context env) { return env; } -inline jsi::Function globalType(jsi::Runtime& env, const char* name) +inline fbjsi::Function globalType(fbjsi::Runtime& env, const char* name) { return env.global().getPropertyAsFunction(env, name); } diff --git a/src/hermes/hermes_value.hpp b/src/jsi/jsi_value.hpp similarity index 69% rename from src/hermes/hermes_value.hpp rename to src/jsi/jsi_value.hpp index 4ac1bb1e7c..371acb9fc3 100644 --- a/src/hermes/hermes_value.hpp +++ b/src/jsi/jsi_value.hpp @@ -18,15 +18,17 @@ #pragma once -#include "hermes_string.hpp" -#include "hermes_types.hpp" +#include "jsi_string.hpp" +#include "jsi_types.hpp" //#include "node_buffer.hpp" namespace realm { namespace js { +namespace fbjsi = facebook::jsi; + template <> -inline const char* hermes::Value::typeof(JsiEnv env, const JsiVal& value) +inline const char* realmjsi::Value::typeof(JsiEnv env, const JsiVal& value) { if (value->isNull()) { return "null"; @@ -50,63 +52,63 @@ inline const char* hermes::Value::typeof(JsiEnv env, const JsiVal& value) } template <> -inline bool hermes::Value::is_array(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_array(JsiEnv env, const JsiVal& value) { return value->isObject() && value->getObject(env).isArray(env); } template <> -inline bool hermes::Value::is_array_buffer(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_array_buffer(JsiEnv env, const JsiVal& value) { return value->isObject() && value->getObject(env).isArrayBuffer(env); } template <> -inline bool hermes::Value::is_array_buffer_view(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_array_buffer_view(JsiEnv env, const JsiVal& value) { return globalType(env, "ArrayBuffer").getPropertyAsFunction(env, "isView").call(env, value).getBool(); } template <> -inline bool hermes::Value::is_date(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_date(JsiEnv env, const JsiVal& value) { return value->isObject() && value->getObject(env).instanceOf(env, env->global().getPropertyAsFunction(env, "Date")); } template <> -inline bool hermes::Value::is_boolean(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_boolean(JsiEnv env, const JsiVal& value) { return value->isBool(); } template <> -inline bool hermes::Value::is_constructor(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_constructor(JsiEnv env, const JsiVal& value) { return value->isObject() && value->getObject(env).isFunction(env); } template <> -inline bool hermes::Value::is_error(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_error(JsiEnv env, const JsiVal& value) { return value->isObject() && value->getObject(env).instanceOf(env, env->global().getPropertyAsFunction(env, "Error")); } template <> -inline bool hermes::Value::is_function(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_function(JsiEnv env, const JsiVal& value) { return value->isObject() && value->getObject(env).isFunction(env); } template <> -inline bool hermes::Value::is_null(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_null(JsiEnv env, const JsiVal& value) { return value->isNull(); } template <> -inline bool hermes::Value::is_number(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_number(JsiEnv env, const JsiVal& value) { return value->isNumber(); } @@ -122,85 +124,85 @@ inline bool is_bson_type(JsiEnv env, const JsiVal& value, std::string type) return false; } - return jsi::Value::strictEquals(env, bsonType, JsiVal(str(env, type))); + return fbjsi::Value::strictEquals(env, bsonType, JsiVal(str(env, type))); } template <> -inline bool hermes::Value::is_decimal128(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_decimal128(JsiEnv env, const JsiVal& value) { return is_bson_type(env, value, "Decimal128"); } template <> -inline bool hermes::Value::is_object_id(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_object_id(JsiEnv env, const JsiVal& value) { return is_bson_type(env, value, "ObjectID"); } template <> -inline bool hermes::Value::is_object(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_object(JsiEnv env, const JsiVal& value) { return value->isObject(); } template <> -inline bool hermes::Value::is_string(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_string(JsiEnv env, const JsiVal& value) { return value->isString(); } template <> -inline bool hermes::Value::is_undefined(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_undefined(JsiEnv env, const JsiVal& value) { return value->isUndefined(); } template <> -inline bool hermes::Value::is_binary(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_binary(JsiEnv env, const JsiVal& value) { return Value::is_array_buffer(env, value) || Value::is_array_buffer_view(env, value); } template <> -inline bool hermes::Value::is_valid(const JsiVal& value) +inline bool realmjsi::Value::is_valid(const JsiVal& value) { return true; // XXX } template <> -inline bool hermes::Value::is_uuid(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::is_uuid(JsiEnv env, const JsiVal& value) { return is_bson_type(env, value, "UUID"); } template <> -inline JsiVal hermes::Value::from_boolean(JsiEnv env, bool boolean) +inline JsiVal realmjsi::Value::from_boolean(JsiEnv env, bool boolean) { return JsiVal(env, boolean); } template <> -inline JsiVal hermes::Value::from_null(JsiEnv env) +inline JsiVal realmjsi::Value::from_null(JsiEnv env) { return env.null(); } template <> -inline JsiVal hermes::Value::from_number(JsiEnv env, double number) +inline JsiVal realmjsi::Value::from_number(JsiEnv env, double number) { return JsiVal(env, number); } template <> -inline JsiVal hermes::Value::from_nonnull_string(JsiEnv env, const hermes::String& string) +inline JsiVal realmjsi::Value::from_nonnull_string(JsiEnv env, const realmjsi::String& string) { return str(env, StringData(string)); } template <> -inline JsiVal hermes::Value::from_nonnull_binary(JsiEnv env, BinaryData data) +inline JsiVal realmjsi::Value::from_nonnull_binary(JsiEnv env, BinaryData data) { - jsi::ArrayBuffer buffer = + fbjsi::ArrayBuffer buffer = globalType(env, "ArrayBuffer").callAsConstructor(env, double(data.size())).getObject(env).getArrayBuffer(env); if (data.size()) { @@ -211,13 +213,13 @@ inline JsiVal hermes::Value::from_nonnull_binary(JsiEnv env, BinaryData data) } template <> -inline JsiVal hermes::Value::from_undefined(JsiEnv env) +inline JsiVal realmjsi::Value::from_undefined(JsiEnv env) { return env.undefined(); } template <> -inline JsiVal hermes::Value::from_uuid(JsiEnv env, const UUID& uuid) +inline JsiVal realmjsi::Value::from_uuid(JsiEnv env, const UUID& uuid) { return env(globalType(env, "Realm") .getPropertyAsFunction(env, "_UUID") @@ -225,19 +227,19 @@ inline JsiVal hermes::Value::from_uuid(JsiEnv env, const UUID& uuid) } template <> -inline bool hermes::Value::to_boolean(JsiEnv env, const JsiVal& value) +inline bool realmjsi::Value::to_boolean(JsiEnv env, const JsiVal& value) { return value->getBool(); // XXX should do conversion. } template <> -inline hermes::String hermes::Value::to_string(JsiEnv env, const JsiVal& value) +inline realmjsi::String realmjsi::Value::to_string(JsiEnv env, const JsiVal& value) { return value->toString(env).utf8(env); } template <> -inline double hermes::Value::to_number(JsiEnv env, const JsiVal& value) +inline double realmjsi::Value::to_number(JsiEnv env, const JsiVal& value) { double number = std::nan(""); if (value->isNumber()) { @@ -253,7 +255,7 @@ inline double hermes::Value::to_number(JsiEnv env, const JsiVal& value) } } else if (is_date(env, value)) { - jsi::Object date = value->getObject(env); + fbjsi::Object date = value->getObject(env); number = date.getPropertyAsFunction(env, "getTime").callWithThis(env, date).getNumber(); } if (std::isnan(number)) { @@ -265,7 +267,7 @@ inline double hermes::Value::to_number(JsiEnv env, const JsiVal& value) } template <> -inline OwnedBinaryData hermes::Value::to_binary(JsiEnv env, const JsiVal& value) +inline OwnedBinaryData realmjsi::Value::to_binary(JsiEnv env, const JsiVal& value) { auto obj = value->asObject(env); if (obj.isArrayBuffer(env)) { @@ -284,31 +286,31 @@ inline OwnedBinaryData hermes::Value::to_binary(JsiEnv env, const JsiVal& value) } template <> -inline JsiObj hermes::Value::to_object(JsiEnv env, const JsiVal& value) +inline JsiObj realmjsi::Value::to_object(JsiEnv env, const JsiVal& value) { return env(value->asObject(env)); // XXX convert? } template <> -inline JsiObj hermes::Value::to_array(JsiEnv env, const JsiVal& value) +inline JsiObj realmjsi::Value::to_array(JsiEnv env, const JsiVal& value) { return to_object(env, value); } template <> -inline JsiFunc hermes::Value::to_function(JsiEnv env, const JsiVal& value) +inline JsiFunc realmjsi::Value::to_function(JsiEnv env, const JsiVal& value) { return env(value->asObject(env).asFunction(env)); } template <> -inline JsiFunc hermes::Value::to_constructor(JsiEnv env, const JsiVal& value) +inline JsiFunc realmjsi::Value::to_constructor(JsiEnv env, const JsiVal& value) { return to_function(env, value); } template <> -inline JsiObj hermes::Value::to_date(JsiEnv env, const JsiVal& value) +inline JsiObj realmjsi::Value::to_date(JsiEnv env, const JsiVal& value) { if (value->isString()) { return env(globalType(env, "Date").callAsConstructor(env, value).asObject(env)); @@ -318,10 +320,10 @@ inline JsiObj hermes::Value::to_date(JsiEnv env, const JsiVal& value) } template <> -inline JsiVal hermes::Value::from_decimal128(JsiEnv env, const Decimal128& number) +inline JsiVal realmjsi::Value::from_decimal128(JsiEnv env, const Decimal128& number) { if (number.is_null()) { - return env(jsi::Value::null()); + return env(fbjsi::Value::null()); } return env(globalType(env, "Realm") @@ -331,13 +333,13 @@ inline JsiVal hermes::Value::from_decimal128(JsiEnv env, const Decimal128& numbe } template <> -inline Decimal128 hermes::Value::to_decimal128(JsiEnv env, const JsiVal& value) +inline Decimal128 realmjsi::Value::to_decimal128(JsiEnv env, const JsiVal& value) { return Decimal128(value->toString(env).utf8(env)); } template <> -inline JsiVal hermes::Value::from_object_id(JsiEnv env, const ObjectId& objectId) +inline JsiVal realmjsi::Value::from_object_id(JsiEnv env, const ObjectId& objectId) { return env(globalType(env, "Realm") .getPropertyAsFunction(env, "_ObjectId") @@ -345,7 +347,7 @@ inline JsiVal hermes::Value::from_object_id(JsiEnv env, const ObjectId& objectId } template <> -inline ObjectId hermes::Value::to_object_id(JsiEnv env, const JsiVal& value) +inline ObjectId realmjsi::Value::to_object_id(JsiEnv env, const JsiVal& value) { auto objectId = value->asObject(env); return ObjectId(objectId.getPropertyAsFunction(env, "toHexString") @@ -356,7 +358,7 @@ inline ObjectId hermes::Value::to_object_id(JsiEnv env, const JsiVal& value) } template <> -inline UUID hermes::Value::to_uuid(JsiEnv env, const JsiVal& value) +inline UUID realmjsi::Value::to_uuid(JsiEnv env, const JsiVal& value) { auto uuid = value->asObject(env); return UUID(