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