1 #include "Shareables.h" 2 3 using namespace facebook; 4 5 namespace reanimated { 6 7 CoreFunction::CoreFunction( 8 JSRuntimeHelper *runtimeHelper, 9 const jsi::Value &workletValue) 10 : runtimeHelper_(runtimeHelper) { 11 jsi::Runtime &rt = *runtimeHelper->rnRuntime(); 12 auto workletObject = workletValue.asObject(rt); 13 rnFunction_ = std::make_unique<jsi::Function>(workletObject.asFunction(rt)); 14 functionBody_ = workletObject.getPropertyAsObject(rt, "__initData") 15 .getProperty(rt, "code") 16 .asString(rt) 17 .utf8(rt); 18 location_ = "worklet_" + 19 std::to_string(static_cast<uint64_t>( 20 workletObject.getProperty(rt, "__workletHash").getNumber())); 21 } 22 23 std::unique_ptr<jsi::Function> &CoreFunction::getFunction(jsi::Runtime &rt) { 24 if (runtimeHelper_->isUIRuntime(rt)) { 25 if (uiFunction_ == nullptr) { 26 // maybe need to initialize UI Function 27 // the newline before closing paren is needed because the last line can be 28 // an inline comment (specifically this happens when we attach source maps 29 // at the end) in which case the paren won't be parsed 30 auto codeBuffer = std::make_shared<const jsi::StringBuffer>( 31 "(" + functionBody_ + "\n)"); 32 uiFunction_ = std::make_unique<jsi::Function>( 33 rt.evaluateJavaScript(codeBuffer, location_) 34 .asObject(rt) 35 .asFunction(rt)); 36 } 37 return uiFunction_; 38 } else { 39 // running on the main RN runtime 40 return rnFunction_; 41 } 42 } 43 44 std::shared_ptr<Shareable> extractShareableOrThrow( 45 jsi::Runtime &rt, 46 const jsi::Value &maybeShareableValue, 47 const char *errorMessage) { 48 if (maybeShareableValue.isObject()) { 49 auto object = maybeShareableValue.asObject(rt); 50 if (object.isHostObject<ShareableJSRef>(rt)) { 51 return object.getHostObject<ShareableJSRef>(rt)->value(); 52 } 53 } else if (maybeShareableValue.isUndefined()) { 54 return Shareable::undefined(); 55 } 56 throw std::runtime_error( 57 errorMessage != nullptr 58 ? errorMessage 59 : "expecting the object to be of type ShareableJSRef"); 60 } 61 62 Shareable::~Shareable() {} 63 64 ShareableArray::ShareableArray(jsi::Runtime &rt, const jsi::Array &array) 65 : Shareable(ArrayType) { 66 auto size = array.size(rt); 67 data_.reserve(size); 68 for (size_t i = 0; i < size; i++) { 69 data_.push_back(extractShareableOrThrow(rt, array.getValueAtIndex(rt, i))); 70 } 71 } 72 73 ShareableObject::ShareableObject(jsi::Runtime &rt, const jsi::Object &object) 74 : Shareable(ObjectType) { 75 auto propertyNames = object.getPropertyNames(rt); 76 auto size = propertyNames.size(rt); 77 data_.reserve(size); 78 for (size_t i = 0; i < size; i++) { 79 auto key = propertyNames.getValueAtIndex(rt, i).asString(rt); 80 auto value = extractShareableOrThrow(rt, object.getProperty(rt, key)); 81 data_.emplace_back(key.utf8(rt), value); 82 } 83 } 84 85 std::shared_ptr<Shareable> Shareable::undefined() { 86 static auto undefined = std::make_shared<ShareableScalar>(); 87 return undefined; 88 } 89 90 } /* namespace reanimated */ 91