1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #include "JavaScriptValue.h" 4 5 #include "JavaScriptRuntime.h" 6 #include "JavaScriptObject.h" 7 8 namespace expo { 9 void JavaScriptValue::registerNatives() { 10 registerHybrid({ 11 makeNativeMethod("kind", JavaScriptValue::jniKind), 12 makeNativeMethod("isNull", JavaScriptValue::isNull), 13 makeNativeMethod("isUndefined", JavaScriptValue::isUndefined), 14 makeNativeMethod("isBool", JavaScriptValue::isBool), 15 makeNativeMethod("isNumber", JavaScriptValue::isNumber), 16 makeNativeMethod("isString", JavaScriptValue::isString), 17 makeNativeMethod("isSymbol", JavaScriptValue::isSymbol), 18 makeNativeMethod("isFunction", JavaScriptValue::isFunction), 19 makeNativeMethod("isArray", JavaScriptValue::isArray), 20 makeNativeMethod("isObject", JavaScriptValue::isObject), 21 makeNativeMethod("getBool", JavaScriptValue::getBool), 22 makeNativeMethod("getDouble", JavaScriptValue::getDouble), 23 makeNativeMethod("getString", JavaScriptValue::jniGetString), 24 makeNativeMethod("getObject", JavaScriptValue::getObject), 25 makeNativeMethod("getArray", JavaScriptValue::getArray), 26 }); 27 } 28 29 JavaScriptValue::JavaScriptValue( 30 std::weak_ptr<JavaScriptRuntime> runtime, 31 std::shared_ptr<jsi::Value> jsValue 32 ) : runtimeHolder(std::move(runtime)), jsValue(std::move(jsValue)) { 33 assert(runtimeHolder.lock() != nullptr); 34 } 35 36 std::shared_ptr<jsi::Value> JavaScriptValue::get() { 37 return jsValue; 38 } 39 40 std::string JavaScriptValue::kind() { 41 if (isNull()) { 42 return "null"; 43 } 44 if (isUndefined()) { 45 return "undefined"; 46 } 47 if (isBool()) { 48 return "boolean"; 49 } 50 if (isNumber()) { 51 return "number"; 52 } 53 if (isString()) { 54 return "string"; 55 } 56 if (isSymbol()) { 57 return "symbol"; 58 } 59 if (isFunction()) { 60 return "function"; 61 } 62 if (isArray()) { 63 return "array"; 64 } 65 if (isObject()) { 66 return "object"; 67 } 68 69 // TODO(@lukmccall): maybe throw exception? 70 return "unknown"; 71 } 72 73 bool JavaScriptValue::isNull() { 74 return jsValue->isNull(); 75 } 76 77 bool JavaScriptValue::isUndefined() { 78 return jsValue->isUndefined(); 79 } 80 81 bool JavaScriptValue::isBool() { 82 return jsValue->isBool(); 83 } 84 85 bool JavaScriptValue::isNumber() { 86 return jsValue->isNumber(); 87 } 88 89 bool JavaScriptValue::isString() { 90 return jsValue->isString(); 91 } 92 93 bool JavaScriptValue::isSymbol() { 94 return jsValue->isSymbol(); 95 } 96 97 bool JavaScriptValue::isFunction() { 98 if (jsValue->isObject()) { 99 auto runtime = runtimeHolder.lock(); 100 assert(runtime != nullptr); 101 return jsValue->asObject(*runtime->get()).isFunction(*runtime->get()); 102 } 103 104 return false; 105 } 106 107 bool JavaScriptValue::isArray() { 108 if (jsValue->isObject()) { 109 auto runtime = runtimeHolder.lock(); 110 assert(runtime != nullptr); 111 return jsValue->asObject(*runtime->get()).isArray(*runtime->get()); 112 } 113 114 return false; 115 } 116 117 bool JavaScriptValue::isObject() { 118 return jsValue->isObject(); 119 } 120 121 bool JavaScriptValue::getBool() { 122 return jsValue->getBool(); 123 } 124 125 double JavaScriptValue::getDouble() { 126 return jsValue->getNumber(); 127 } 128 129 std::string JavaScriptValue::getString() { 130 auto runtime = runtimeHolder.lock(); 131 assert(runtime != nullptr); 132 return jsValue->getString(*runtime->get()).utf8(*runtime->get()); 133 } 134 135 jni::local_ref<JavaScriptObject::javaobject> JavaScriptValue::getObject() { 136 auto runtime = runtimeHolder.lock(); 137 assert(runtime != nullptr); 138 auto jsObject = std::make_shared<jsi::Object>(jsValue->getObject(*runtime->get())); 139 return JavaScriptObject::newObjectCxxArgs(runtimeHolder, jsObject); 140 } 141 142 jni::local_ref<jni::JArrayClass<JavaScriptValue::javaobject>> JavaScriptValue::getArray() { 143 auto runtime = runtimeHolder.lock(); 144 assert(runtime != nullptr); 145 146 auto jsArray = jsValue 147 ->getObject(*runtime->get()) 148 .asArray(*runtime->get()); 149 size_t size = jsArray.size(*runtime->get()); 150 151 auto result = jni::JArrayClass<JavaScriptValue::javaobject>::newArray(size); 152 for (size_t i = 0; i < size; i++) { 153 auto element = JavaScriptValue::newObjectCxxArgs( 154 runtimeHolder, 155 std::make_shared<jsi::Value>(jsArray.getValueAtIndex(*runtime->get(), i)) 156 ); 157 158 result->setElement(i, element.release()); 159 } 160 return result; 161 } 162 163 jni::local_ref<jstring> JavaScriptValue::jniKind() { 164 auto result = kind(); 165 return jni::make_jstring(result); 166 } 167 168 jni::local_ref<jstring> JavaScriptValue::jniGetString() { 169 auto result = getString(); 170 return jni::make_jstring(result); 171 } 172 } // namespace expo 173