1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_JSI_JSI_TYPES_H 17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_JSI_JSI_TYPES_H 18 19 #include <string> 20 21 #include "ecmascript/napi/include/jsnapi.h" 22 23 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h" 24 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_fwd.h" 25 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_value_conversions.h" 26 27 #define FAKE_PTR_FOR_FUNCTION_ACCESS(klass) \ 28 const klass* operator->() const \ 29 { \ 30 return this; \ 31 } 32 33 namespace OHOS::Ace::Framework { 34 35 using JsiFunctionCallback = panda::Local<panda::JSValueRef> (*)(panda::JsiRuntimeCallInfo*); 36 using EcmaVM = panda::ecmascript::EcmaVM; 37 38 template<typename T> 39 class JsiType { 40 public: 41 JsiType() = default; 42 JsiType(const JsiType& rhs); 43 JsiType(JsiType&& rhs); 44 virtual ~JsiType() = default; 45 46 explicit JsiType(panda::Local<T> val); 47 explicit JsiType(const panda::CopyableGlobal<T>& other); 48 explicit JsiType(const EcmaVM *vm, panda::Local<T> val); 49 50 template<typename S> 51 explicit JsiType(panda::Local<S> val); 52 53 JsiType& operator=(const JsiType& rhs); 54 JsiType& operator=(JsiType&& rhs); 55 56 template<typename S> Cast(const JsiType<S> & that)57 static JsiType<T> Cast(const JsiType<S>& that) 58 { 59 return JsiType<T>(that.GetHandle()); 60 } 61 62 template<class... Args> 63 static JsiType<T> New(Args &&... args); 64 65 void SetWeakCallback(void *ref, panda::WeakRefClearCallBack callback); 66 const panda::CopyableGlobal<T>& GetHandle() const; 67 const panda::CopyableGlobal<T>& operator->() const; 68 Local<T> GetLocalHandle() const; 69 bool IsEmpty() const; 70 bool IsWeak() const; 71 void Reset(); 72 operator panda::CopyableGlobal<T>() const; 73 74 const EcmaVM* GetEcmaVM() const; 75 76 private: 77 panda::CopyableGlobal<T> handle_; 78 }; 79 80 class JsiValue : public JsiType<panda::JSValueRef> { 81 public: 82 JsiValue() = default; 83 explicit JsiValue(const panda::CopyableGlobal<panda::JSValueRef>& val); 84 explicit JsiValue(panda::Local<panda::JSValueRef> val); 85 explicit JsiValue(const EcmaVM *vm, panda::Local<panda::JSValueRef> val); 86 ~JsiValue() override = default; 87 88 bool IsEmpty() const; 89 bool IsFunction() const; 90 bool IsNumber() const; 91 bool IsString() const; 92 bool IsBoolean() const; 93 bool IsObject() const; 94 bool IsArray() const; 95 bool IsArrayBuffer() const; 96 bool IsUint8ClampedArray() const; 97 bool IsUndefined() const; 98 bool IsNull() const; 99 std::string ToString() const; 100 bool ToBoolean() const; 101 102 template<typename T> 103 T ToNumber() const; 104 105 static JsiRef<JsiValue> Undefined(); 106 static JsiRef<JsiValue> Null(); 107 static JsiRef<JsiValue> True(); 108 static JsiRef<JsiValue> False(); 109 110 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiValue) 111 }; 112 113 /** 114 * @brief A wrapper around a panda::StringRef 115 * 116 */ 117 class JsiString : public JsiType<panda::StringRef> { 118 public: 119 JsiString() = default; 120 explicit JsiString(panda::Local<panda::StringRef> val); 121 explicit JsiString(const panda::CopyableGlobal<panda::StringRef>& val); 122 ~JsiString() override = default; 123 124 static panda::Local<panda::StringRef> New(const char* str); 125 static panda::Local<panda::StringRef> New(const std::string& str); 126 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiString) 127 }; 128 129 /** 130 * @brief A wrapper around a panda::ArrayRef 131 * 132 */ 133 class JsiArray : public JsiType<panda::ArrayRef> { 134 public: 135 JsiArray(); 136 explicit JsiArray(panda::Local<panda::ArrayRef> val); 137 explicit JsiArray(const EcmaVM *vm, panda::Local<panda::ArrayRef> val); 138 explicit JsiArray(const panda::CopyableGlobal<panda::ArrayRef>& val); 139 ~JsiArray() override = default; 140 JsiRef<JsiValue> GetValueAt(size_t index) const; 141 void SetValueAt(size_t index, JsiRef<JsiValue> value) const; 142 JsiRef<JsiValue> GetProperty(const char* prop) const; 143 JsiRef<JsiValue> GetProperty(int32_t propertyIndex) const; 144 size_t Length() const; 145 void SetLength(size_t length) const; 146 bool IsArray() const; 147 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiArray) 148 }; 149 150 /** 151 * @brief A wrapper around a panda::ArrayBufferRef 152 * 153 */ 154 class JsiArrayBuffer : public JsiType<panda::ArrayBufferRef> { 155 public: 156 JsiArrayBuffer() = default; 157 explicit JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val); 158 explicit JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef>& val); 159 int32_t ByteLength() const; 160 void* GetBuffer() const; 161 void Detach() const; 162 bool IsDetach() const; 163 ~JsiArrayBuffer() override = default; 164 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiArrayBuffer) 165 }; 166 167 /** 168 * @brief A wrapper around a panda::Uint8ClampedArrayRef 169 * 170 */ 171 class JsiUint8ClampedArray : public JsiType<panda::Uint8ClampedArrayRef> { 172 public: 173 JsiUint8ClampedArray() = default; 174 explicit JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val); 175 explicit JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef>& val); 176 ~JsiUint8ClampedArray() override = default; 177 JsiRef<JsiArrayBuffer> GetArrayBuffer() const; 178 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiUint8ClampedArray) 179 }; 180 181 /** 182 * @brief A wrapper around panda::ObjectRef 183 * 184 */ 185 class JsiObject : public JsiType<panda::ObjectRef> { 186 public: 187 JsiObject(); 188 explicit JsiObject(panda::Local<panda::ObjectRef> val); 189 explicit JsiObject(const EcmaVM *vm, panda::Local<panda::ObjectRef> val); 190 explicit JsiObject(const panda::CopyableGlobal<panda::ObjectRef>& val); 191 bool IsUndefined() const; 192 ~JsiObject() override = default; 193 enum InternalFieldIndex { INSTANCE = 0 }; 194 195 template<typename T> 196 T* Unwrap() const; 197 198 template<typename T> 199 void Wrap(T* data) const; 200 201 JsiRef<JsiArray> GetPropertyNames() const; 202 JsiRef<JsiValue> GetProperty(const char* prop) const; 203 JsiRef<JsiValue> GetProperty(int32_t propertyIndex) const; 204 bool HasProperty(int32_t propertyIndex) const; 205 bool HasProperty(const char* prop) const; 206 JsiRef<JsiValue> ToJsonObject(const char* value) const; 207 208 template<typename T> 209 T GetPropertyValue(int32_t propertyIndex, T defaultValue) const; 210 211 template<typename T> 212 T GetPropertyValue(const char* prop, T defaultValue) const; 213 214 template<typename T> 215 void SetProperty(int32_t propertyIndex, const T value) const; 216 217 template<typename T> 218 void SetProperty(const char* prop, const T value) const; 219 void SetPropertyJsonObject(const char* prop, const char* value) const; 220 void SetPropertyObject(const char* prop, JsiRef<JsiValue> value) const; 221 222 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiObject) 223 }; 224 225 /** 226 * @brief A wrapper around panda::FunctionRef 227 * 228 */ 229 class JsiFunction : public JsiType<panda::FunctionRef> { 230 public: 231 JsiFunction(); 232 explicit JsiFunction(panda::Local<panda::FunctionRef> val); 233 explicit JsiFunction(const EcmaVM *vm, panda::Local<panda::FunctionRef> val); 234 explicit JsiFunction(const panda::CopyableGlobal<panda::FunctionRef>& val); 235 ~JsiFunction() override = default; 236 237 JsiRef<JsiValue> Call(JsiRef<JsiValue> thisVal, int argc = 0, JsiRef<JsiValue> argv[] = nullptr) const; 238 static panda::Local<panda::FunctionRef> New(JsiFunctionCallback func); 239 240 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiFunction) 241 }; 242 243 class JsiObjTemplate : public JsiObject { 244 public: 245 JsiObjTemplate() = default; 246 explicit JsiObjTemplate(panda::Local<panda::ObjectRef> val); 247 explicit JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef>& val); 248 ~JsiObjTemplate() override = default; 249 250 void SetInternalFieldCount(int32_t count) const; 251 JsiRef<JsiObject> NewInstance() const; 252 static panda::Local<panda::JSValueRef> New(); 253 254 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiObjTemplate) 255 }; 256 257 struct JsiExecutionContext { 258 panda::ecmascript::EcmaVM* vm_ = nullptr; 259 }; 260 261 class JsiCallbackInfo { 262 public: 263 JsiCallbackInfo(panda::JsiRuntimeCallInfo* info); 264 ~JsiCallbackInfo() = default; 265 JsiCallbackInfo(const JsiCallbackInfo&) = delete; 266 JsiCallbackInfo& operator=(const JsiCallbackInfo&) = delete; 267 268 JsiRef<JsiValue> operator[](size_t index) const; 269 JsiRef<JsiObject> This() const; 270 int Length() const; 271 272 template<typename T> 273 void SetReturnValue(T* instance) const; 274 275 template<typename T> 276 void SetReturnValue(JsiRef<T> val) const; 277 278 void ReturnSelf() const; 279 GetReturnValue()280 std::variant<void*, panda::CopyableGlobal<panda::JSValueRef>> GetReturnValue() 281 { 282 return retVal_; 283 } 284 GetJsiRuntimeCallInfo()285 panda::JsiRuntimeCallInfo* GetJsiRuntimeCallInfo() const 286 { 287 return info_; 288 } 289 GetExecutionContext()290 JsiExecutionContext GetExecutionContext() const 291 { 292 return JsiExecutionContext { info_->GetVM() }; 293 } 294 GetVm()295 panda::ecmascript::EcmaVM* GetVm() const 296 { 297 return info_->GetVM(); 298 } 299 SetSize(size_t size)300 void SetSize(size_t size) const 301 { 302 size_ = size; 303 } 304 GetSize()305 size_t GetSize() const 306 { 307 return size_; 308 } 309 310 template<typename T> 311 T* UnwrapArg(size_t index) const; 312 bool GetBooleanArg(size_t index, bool& value) const; 313 bool GetInt32Arg(size_t index, int32_t& value) const; 314 bool GetUint32Arg(size_t index, uint32_t& value) const; 315 bool GetDoubleArg(size_t index, double& value) const; 316 bool GetDoubleArrayArg(size_t index, std::vector<double>& valueArr) const; 317 bool GetStringArg(size_t index, std::string& value) const; 318 319 private: 320 mutable size_t size_ = 0; 321 panda::JsiRuntimeCallInfo* info_ = nullptr; 322 mutable std::variant<void*, panda::CopyableGlobal<panda::JSValueRef>> retVal_; 323 }; 324 325 class JsiGCMarkCallbackInfo { 326 public: 327 template<typename T> Mark(const JsiRef<T> & val)328 void Mark(const JsiRef<T>& val) const 329 {} 330 }; 331 332 class JsiDate : public JsiType<panda::DateRef> { 333 public: 334 JsiDate() = default; 335 explicit JsiDate(panda::Local<panda::DateRef> val); 336 explicit JsiDate(const panda::CopyableGlobal<panda::DateRef>& val); 337 ~JsiDate() override = default; 338 339 static JsiRef<JsiValue> New(double value); 340 FAKE_PTR_FOR_FUNCTION_ACCESS(JsiDate) 341 }; 342 343 class JsiException { 344 public: 345 template<typename... Args> 346 static void Throw(const char* format, Args... args); 347 template<typename... Args> 348 static void Throw(int32_t code, const char* format, Args... args); 349 template<typename... Args> 350 static void ThrowRangeError(const char* format, Args... args); 351 template<typename... Args> 352 static void ThrowReferenceError(const char* format, Args... args); 353 template<typename... Args> 354 static void ThrowSyntaxError(const char* format, Args... args); 355 template<typename... Args> 356 static void ThrowTypeError(const char* format, Args... args); 357 template<typename... Args> 358 static void ThrowEvalError(const char* format, Args... args); 359 }; 360 361 } // namespace OHOS::Ace::Framework 362 363 #include "jsi_types.inl" 364 365 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_JSI_JSI_TYPES_H 366