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 runtimeHolder.ensureRuntimeIsValid(); 34 } 35 36 JavaScriptValue::JavaScriptValue( 37 WeakRuntimeHolder runtime, 38 std::shared_ptr<jsi::Value> jsValue 39 ) : runtimeHolder(std::move(runtime)), jsValue(std::move(jsValue)) { 40 runtimeHolder.ensureRuntimeIsValid(); 41 } 42 43 std::shared_ptr<jsi::Value> JavaScriptValue::get() { 44 return jsValue; 45 } 46 47 std::string JavaScriptValue::kind() { 48 if (isNull()) { 49 return "null"; 50 } 51 if (isUndefined()) { 52 return "undefined"; 53 } 54 if (isBool()) { 55 return "boolean"; 56 } 57 if (isNumber()) { 58 return "number"; 59 } 60 if (isString()) { 61 return "string"; 62 } 63 if (isSymbol()) { 64 return "symbol"; 65 } 66 if (isFunction()) { 67 return "function"; 68 } 69 if (isArray()) { 70 return "array"; 71 } 72 if (isObject()) { 73 return "object"; 74 } 75 76 // TODO(@lukmccall): maybe throw exception? 77 return "unknown"; 78 } 79 80 bool JavaScriptValue::isNull() { 81 return jsValue->isNull(); 82 } 83 84 bool JavaScriptValue::isUndefined() { 85 return jsValue->isUndefined(); 86 } 87 88 bool JavaScriptValue::isBool() { 89 return jsValue->isBool(); 90 } 91 92 bool JavaScriptValue::isNumber() { 93 return jsValue->isNumber(); 94 } 95 96 bool JavaScriptValue::isString() { 97 return jsValue->isString(); 98 } 99 100 bool JavaScriptValue::isSymbol() { 101 return jsValue->isSymbol(); 102 } 103 104 bool JavaScriptValue::isFunction() { 105 if (jsValue->isObject()) { 106 auto &jsRuntime = runtimeHolder.getJSRuntime(); 107 return jsValue->asObject(jsRuntime).isFunction(jsRuntime); 108 } 109 110 return false; 111 } 112 113 bool JavaScriptValue::isArray() { 114 if (jsValue->isObject()) { 115 auto &jsRuntime = runtimeHolder.getJSRuntime(); 116 return jsValue->asObject(jsRuntime).isArray(jsRuntime); 117 } 118 119 return false; 120 } 121 122 bool JavaScriptValue::isObject() { 123 return jsValue->isObject(); 124 } 125 126 bool JavaScriptValue::getBool() { 127 return jsValue->getBool(); 128 } 129 130 double JavaScriptValue::getDouble() { 131 return jsValue->getNumber(); 132 } 133 134 std::string JavaScriptValue::getString() { 135 auto &jsRuntime = runtimeHolder.getJSRuntime(); 136 return jsValue->getString(jsRuntime).utf8(jsRuntime); 137 } 138 139 jni::local_ref<JavaScriptObject::javaobject> JavaScriptValue::getObject() { 140 auto &jsRuntime = runtimeHolder.getJSRuntime(); 141 auto jsObject = std::make_shared<jsi::Object>(jsValue->getObject(jsRuntime)); 142 return JavaScriptObject::newObjectCxxArgs(runtimeHolder, jsObject); 143 } 144 145 jni::local_ref<jni::JArrayClass<JavaScriptValue::javaobject>> JavaScriptValue::getArray() { 146 auto &jsRuntime = runtimeHolder.getJSRuntime(); 147 148 auto jsArray = jsValue 149 ->getObject(jsRuntime) 150 .asArray(jsRuntime); 151 size_t size = jsArray.size(jsRuntime); 152 153 auto result = jni::JArrayClass<JavaScriptValue::javaobject>::newArray(size); 154 for (size_t i = 0; i < size; i++) { 155 auto element = JavaScriptValue::newObjectCxxArgs( 156 runtimeHolder, 157 std::make_shared<jsi::Value>(jsArray.getValueAtIndex(jsRuntime, i)) 158 ); 159 160 result->setElement(i, element.release()); 161 } 162 return result; 163 } 164 165 jni::local_ref<jstring> JavaScriptValue::jniKind() { 166 auto result = kind(); 167 return jni::make_jstring(result); 168 } 169 170 jni::local_ref<jstring> JavaScriptValue::jniGetString() { 171 auto result = getString(); 172 return jni::make_jstring(result); 173 } 174 } // namespace expo 175