Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Build Android
on:
push:
branches:
- main
- 0.x
paths:
- '.github/workflows/build-android.yml'
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Build iOS
on:
push:
branches:
- main
- 0.x
paths:
- '.github/workflows/build-ios.yml'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-lockfiles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: 'Update Lockfiles (bun.lockb + Podfile.lock)'
on:
push:
branches:
- main
- 0.x
paths:
- ".github/workflows/update-lockfiles.yml"
pull_request:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/validate-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Validate Android
on:
push:
branches:
- main
- 0.x
paths:
- '.github/workflows/validate-android.yml'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/validate-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: 'Validate C++'
on:
push:
branches:
- main
- 0.x
paths:
- '.github/workflows/validate-cpp.yml'
Expand Down Expand Up @@ -35,4 +34,5 @@ jobs:
,-build/namespaces\
,-whitespace/comments\
,-build/include_order\
,-whitespace/parens\
"
1 change: 0 additions & 1 deletion .github/workflows/validate-js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Validate JS
on:
push:
branches:
- main
- 0.x
paths:
- '.github/workflows/validate-js.yml'
Expand Down
9 changes: 9 additions & 0 deletions android/src/main/cpp/cpp-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#include <fbjni/fbjni.h>
#include <jni.h>
#include <jsi/jsi.h>
#include <memory>

#include "MGLQuickCryptoHostObject.h"
#include "JSIUtils/MGLTypedArray.h"

using namespace facebook;

Expand All @@ -28,6 +30,13 @@ class CryptoCppAdapter : public jni::HybridClass<CryptoCppAdapter> {
auto object = jsi::Object::createFromHostObject(runtime, hostObject);
runtime.global().setProperty(runtime, "__QuickCryptoProxy",
std::move(object));
// Adds the PropNameIDCache object to the Runtime. If the Runtime gets destroyed, the Object gets destroyed and the cache gets invalidated.
auto propNameIdCache = std::make_shared<InvalidateCacheOnDestroy>(runtime);
runtime.global().setProperty(
runtime,
"rnqcArrayBufferPropNameIdCache",
jsi::Object::createFromHostObject(runtime, propNameIdCache)
);
}

void nativeInstall(
Expand Down
55 changes: 38 additions & 17 deletions cpp/JSIUtils/MGLTypedArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>
#include <string>
#include <unordered_map>

Expand Down Expand Up @@ -40,33 +42,37 @@ enum class Prop {
class PropNameIDCache {
public:
const jsi::PropNameID &get(jsi::Runtime &runtime, Prop prop) {
if (!this->props[prop]) {
this->props[prop] =
std::make_unique<jsi::PropNameID>(createProp(runtime, prop));
auto key = reinterpret_cast<uintptr_t>(&runtime);
if (this->props.find(key) == this->props.end()) {
this->props[key] = std::unordered_map<Prop, std::unique_ptr<jsi::PropNameID>>();
}
return *(this->props[prop]);
if (!this->props[key][prop]) {
this->props[key][prop] = std::make_unique<jsi::PropNameID>(createProp(runtime, prop));
}
return *(this->props[key][prop]);
}

const jsi::PropNameID &getConstructorNameProp(jsi::Runtime &runtime,
MGLTypedArrayKind kind);
const jsi::PropNameID &getConstructorNameProp(jsi::Runtime &runtime, MGLTypedArrayKind kind);

void invalidate() {
/** This call (and attempts to use props.clear()) crash 💥 when the
* JSI runtime has already been destroyed. So we are commenting it out
* and waiting for Nitro and 1.0 to fix this the proper way.
*/
//props.erase(props.begin(), props.end());
void invalidate(uintptr_t key) {
if (props.find(key) != props.end()) {
props[key].clear();
}
}

private:
std::unordered_map<Prop, std::unique_ptr<jsi::PropNameID>> props;
std::unordered_map<uintptr_t, std::unordered_map<Prop, std::unique_ptr<jsi::PropNameID>>> props;

jsi::PropNameID createProp(jsi::Runtime &runtime, Prop prop);
};

PropNameIDCache propNameIDCache;

void invalidateJsiPropNameIDCache() { propNameIDCache.invalidate(); }
InvalidateCacheOnDestroy::InvalidateCacheOnDestroy(jsi::Runtime &runtime) {
key = reinterpret_cast<uintptr_t>(&runtime);
}
InvalidateCacheOnDestroy::~InvalidateCacheOnDestroy() {
propNameIDCache.invalidate(key);
}

MGLTypedArrayKind getTypedArrayKindForName(const std::string &name);

Expand All @@ -75,8 +81,9 @@ MGLTypedArrayBase::MGLTypedArrayBase(jsi::Runtime &runtime, size_t size,
: MGLTypedArrayBase(
runtime,
runtime.global()
.getProperty(runtime, propNameIDCache.getConstructorNameProp(
runtime, kind))
.getProperty(
runtime,
propNameIDCache.getConstructorNameProp(runtime, kind))
.asObject(runtime)
.asFunction(runtime)
.callAsConstructor(runtime, {static_cast<double>(size)})
Expand Down Expand Up @@ -236,6 +243,20 @@ void MGLTypedArray<T>::update(jsi::Runtime &runtime,
reinterpret_cast<ContentType<T> *>(rawData));
}

template <MGLTypedArrayKind T>
void MGLTypedArray<T>::updateUnsafe(jsi::Runtime &runtime, ContentType<T> *data, size_t length) {
if (length != size(runtime)) {
throw jsi::JSError(runtime, "TypedArray can only be updated with an array of the same size");
}
uint8_t *rawData = getBuffer(runtime).data(runtime) + byteOffset(runtime);
memcpy(rawData, data, length);
}

template <MGLTypedArrayKind T>
uint8_t* MGLTypedArray<T>::data(jsi::Runtime &runtime) {
return getBuffer(runtime).data(runtime) + byteOffset(runtime);
}

const jsi::PropNameID &PropNameIDCache::getConstructorNameProp(
jsi::Runtime &runtime, MGLTypedArrayKind kind) {
switch (kind) {
Expand Down
21 changes: 20 additions & 1 deletion cpp/JSIUtils/MGLTypedArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,24 @@ struct typedArrayTypeMap<MGLTypedArrayKind::Float64Array> {
typedef double type;
};

void invalidateJsiPropNameIDCache();
// Instance of this class will invalidate PropNameIDCache when destructor is called.
// Attach this object to global in specific jsi::Runtime to make sure lifecycle of
// the cache object is connected to the lifecycle of the js runtime
class InvalidateCacheOnDestroy : public jsi::HostObject {
public:
explicit InvalidateCacheOnDestroy(jsi::Runtime &runtime);
virtual ~InvalidateCacheOnDestroy();
virtual jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) {
return jsi::Value::null();
}
virtual void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) {}
virtual std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) {
return {};
}

private:
uintptr_t key;
};

class MGLTypedArrayBase : public jsi::Object {
public:
Expand Down Expand Up @@ -126,6 +143,8 @@ class MGLTypedArray : public MGLTypedArrayBase {

std::vector<ContentType<T>> toVector(jsi::Runtime &runtime);
void update(jsi::Runtime &runtime, const std::vector<ContentType<T>> &data);
void updateUnsafe(jsi::Runtime &runtime, ContentType<T> *data, size_t length);
uint8_t* data(jsi::Runtime &runtime);
};

template <MGLTypedArrayKind T>
Expand Down
2 changes: 1 addition & 1 deletion cpp/MGLQuickCryptoHostObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class JSI_EXPORT MGLQuickCryptoHostObject : public MGLSmartHostObject {
std::shared_ptr<react::CallInvoker> jsCallInvoker,
std::shared_ptr<DispatchQueue::dispatch_queue> workerQueue);

virtual ~MGLQuickCryptoHostObject() { invalidateJsiPropNameIDCache(); }
virtual ~MGLQuickCryptoHostObject() {}
};

} // namespace margelo
Expand Down
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ PODS:
- react-native-quick-base64 (2.1.2):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- react-native-quick-crypto (0.7.6):
- react-native-quick-crypto (0.7.9):
- OpenSSL-Universal
- RCT-Folly (= 2021.07.22.00)
- React
Expand Down Expand Up @@ -628,7 +628,7 @@ SPEC CHECKSUMS:
React-logger: 8edc785c47c8686c7962199a307015e2ce9a0e4f
react-native-fast-encoder: 6f59e9b08e2bc5a8bf1f36e1630cdcfd66dd18af
react-native-quick-base64: 61228d753294ae643294a75fece8e0e80b7558a6
react-native-quick-crypto: 03d888b32a7d58adfe93926ee226c1adc5519c6e
react-native-quick-crypto: d8c6ba8c31de79da1ebbbdb79cf16d1ee980b407
react-native-safe-area-context: ab8f4a3d8180913bd78ae75dd599c94cce3d5e9a
React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a
React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a
Expand Down
10 changes: 10 additions & 0 deletions ios/QuickCryptoModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#import <jsi/jsi.h>

#import "../cpp/MGLQuickCryptoHostObject.h"
#import "../cpp/JSIUtils/MGLTypedArray.h"

@implementation QuickCryptoModule

Expand Down Expand Up @@ -40,6 +41,15 @@ - (void)setBridge:(RCTBridge *)bridge {
auto object = jsi::Object::createFromHostObject(runtime, hostObject);
runtime.global().setProperty(runtime, "__QuickCryptoProxy", std::move(object));

// Adds the PropNameIDCache object to the Runtime. If the Runtime gets
// destroyed, the Object gets destroyed and the cache gets invalidated.
auto propNameIdCache = std::make_shared<InvalidateCacheOnDestroy>(runtime);
runtime.global().setProperty(
runtime,
"rnqcArrayBufferPropNameIdCache",
jsi::Object::createFromHostObject(runtime, propNameIdCache)
);

NSLog(@"Successfully installed JSI bindings for react-native-quick-crypto!");
return @true;
}
Expand Down
Binary file modified test/test_suite_results.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading