1 /* 2 * Copyright (c) 2021-2022 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_V8_V8_TYPES_H 17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_V8_V8_TYPES_H 18 19 #include "v8.h" 20 21 #include "frameworks/bridge/declarative_frontend/engine/v8/v8_declarative_engine.h" 22 #include "frameworks/bridge/declarative_frontend/engine/v8/v8_fwd.h" 23 #include "frameworks/bridge/declarative_frontend/engine/v8/v8_value_conversions.h" 24 25 #define FAKE_PTR_FOR_FUNCTION_ACCESS(klass) \ 26 const klass* operator->() const \ 27 { \ 28 return this; \ 29 } 30 31 namespace OHOS::Ace::Framework { 32 33 template<typename T> 34 using CopyablePersistent = v8::Persistent<T, v8::CopyablePersistentTraits<T>>; 35 using FunctionCallback = void (*)(const v8::FunctionCallbackInfo<v8::Value>&); 36 37 /** 38 * @brief A wrapper around a copyable-persistent V8 handle, inherited by the rest of the specialized wrappers 39 * 40 * @tparam T A v8 type (v8::Value, v8::Object etc.) 41 */ 42 template<typename T> 43 class V8Type { 44 public: 45 V8Type(); 46 V8Type(const V8Type& rhs); 47 V8Type(V8Type&& rhs); 48 virtual ~V8Type(); 49 50 explicit V8Type(v8::Local<T> val); 51 explicit V8Type(CopyablePersistent<T> other); 52 53 template<typename S> 54 explicit V8Type(v8::Local<S> val); 55 56 V8Type& operator=(const V8Type& rhs); 57 V8Type& operator=(V8Type&& rhs); 58 59 template<typename S> Cast(const V8Type<S> & that)60 static V8Type<T> Cast(const V8Type<S>& that) 61 { 62 return V8Type<T>(that.GetHandle()); 63 } 64 65 void SetWeak(); 66 v8::Local<T> GetHandle() const; 67 v8::Local<T> operator->() const; 68 bool IsEmpty() const; 69 bool IsWeak() const; 70 void Reset(); 71 operator v8::Local<T>() const; 72 73 template<typename... Args> 74 static V8Type<T> New(Args&&...); 75 76 private: 77 CopyablePersistent<T> handle_; 78 }; 79 80 /** 81 * @brief A wrapper around v8::Value 82 * 83 */ 84 class V8Value : public V8Type<v8::Value> { 85 public: 86 V8Value(); 87 explicit V8Value(v8::Local<v8::Value> val); 88 ~V8Value() override = default; 89 90 bool IsFunction() const; 91 bool IsNumber() const; 92 bool IsString() const; 93 bool IsBoolean() const; 94 bool IsObject() const; 95 bool IsArray() const; 96 bool IsUndefined() const; 97 bool IsNull() const; 98 std::string ToString() const; 99 bool ToBoolean() const; 100 101 template<typename T> 102 T ToNumber() const; 103 104 FAKE_PTR_FOR_FUNCTION_ACCESS(V8Value) 105 }; 106 107 /** 108 * @brief A wrapper around a v8::Array 109 * 110 */ 111 class V8Array : public V8Type<v8::Array> { 112 public: 113 V8Array(); 114 explicit V8Array(v8::Local<v8::Array> arr); 115 ~V8Array() override = default; 116 V8Ref<V8Value> GetValueAt(size_t index) const; 117 void SetValueAt(size_t index, V8Ref<V8Value> value) const; 118 size_t Length() const; 119 FAKE_PTR_FOR_FUNCTION_ACCESS(V8Array) 120 }; 121 122 /** 123 * @brief A wrapper around v8::Object 124 * 125 */ 126 class V8Object : public V8Type<v8::Object> { 127 public: 128 V8Object(); 129 ~V8Object() override = default; 130 enum InternalFieldIndex { INSTANCE = 0 }; 131 132 FAKE_PTR_FOR_FUNCTION_ACCESS(V8Object) 133 134 template<typename T> 135 T* Unwrap() const; 136 137 template<typename T> 138 void Wrap(T* data) const; 139 140 V8Ref<V8Array> GetPropertyNames() const; 141 V8Ref<V8Value> GetProperty(const char* prop) const; 142 143 template<typename T> 144 void SetProperty(const char* prop, const T value) const; 145 void SetPropertyJsonObject(const char* prop, const char* value) const; 146 void SetPropertyObject(const char* prop, V8Ref<V8Value> value) const; 147 V8Ref<V8Value> GetValueAt(size_t index) const; 148 void SetValueAt(size_t index, V8Ref<V8Value> value) const; 149 150 explicit V8Object(v8::Local<v8::Object> obj); 151 }; 152 153 /** 154 * @brief A wrapper around v8::Function 155 * 156 */ 157 class V8Function : public V8Type<v8::Function> { 158 public: 159 V8Function(); 160 explicit V8Function(v8::Local<v8::Function> obj); 161 ~V8Function() override = default; 162 163 V8Ref<V8Value> Call(V8Ref<V8Value> thisVal, int argc = 0, V8Ref<V8Value> argv[] = nullptr) const; 164 static v8::Local<v8::Function> New(FunctionCallback func); 165 166 FAKE_PTR_FOR_FUNCTION_ACCESS(V8Function) 167 168 private: 169 v8::Isolate* isolate_ = nullptr; 170 CopyablePersistent<v8::Context> ctx_; 171 }; 172 173 class V8ObjTemplate : public V8Type<v8::ObjectTemplate> { 174 public: 175 V8ObjTemplate() = default; V8ObjTemplate(v8::Local<v8::ObjectTemplate> obj)176 explicit V8ObjTemplate(v8::Local<v8::ObjectTemplate> obj) : V8Type(obj) {} 177 178 void SetInternalFieldCount(int32_t count) const; 179 V8Ref<V8Object> NewInstance() const; 180 static v8::Local<v8::ObjectTemplate> New(); 181 182 FAKE_PTR_FOR_FUNCTION_ACCESS(V8ObjTemplate) 183 }; 184 185 class V8String : public V8Type<v8::String> { 186 public: 187 explicit V8String(const char* str); 188 189 FAKE_PTR_FOR_FUNCTION_ACCESS(V8String) 190 191 static V8String New(const char* str); 192 }; 193 194 struct V8ExecutionContext { 195 v8::Isolate* isolate; 196 CopyablePersistent<v8::Context> context; 197 }; 198 199 /** 200 * @brief A wrapper around v8::FunctionCallbackInfo<v8::Value> 201 * 202 */ 203 class V8CallbackInfo { 204 public: 205 V8CallbackInfo(const v8::FunctionCallbackInfo<v8::Value>& info); 206 ~V8CallbackInfo() = default; 207 explicit V8CallbackInfo(const V8CallbackInfo&) = delete; 208 V8CallbackInfo& operator=(const V8CallbackInfo&) = delete; 209 210 V8Ref<V8Value> operator[](size_t index) const; 211 V8Ref<V8Object> This() const; 212 int Length() const; 213 214 template<typename T> 215 void SetReturnValue(T* instance) const; 216 217 template<typename T> 218 void SetReturnValue(V8Ref<T> val) const; 219 220 template<typename S> 221 void SetReturnValue(S any) const; 222 223 void ReturnSelf() const; 224 GetExecutionContext()225 V8ExecutionContext GetExecutionContext() const 226 { 227 return V8ExecutionContext { isolate_, ctx_ }; 228 } 229 230 private: 231 const v8::FunctionCallbackInfo<v8::Value>& info_; 232 CopyablePersistent<v8::Context> ctx_; 233 v8::Isolate* isolate_; 234 }; 235 236 /** 237 * @brief A placeholder class for GC mark callbacks. V8 provides optional second-pass callback to handles 238 * but for this moment we do not need it. 239 * 240 */ 241 class V8GCMarkCallbackInfo { 242 public: 243 template<typename T> Mark(const V8Ref<T> & val)244 void Mark(const V8Ref<T>& val) const 245 {} 246 }; 247 248 class V8Exception { 249 public: 250 template<typename... Args> 251 static void Throw(const char* format, Args... args); 252 template<typename... Args> 253 static void ThrowRangeError(const char* format, Args... args); 254 template<typename... Args> 255 static void ThrowReferenceError(const char* format, Args... args); 256 template<typename... Args> 257 static void ThrowSyntaxError(const char* format, Args... args); 258 template<typename... Args> 259 static void ThrowTypeError(const char* format, Args... args); 260 }; 261 262 } // namespace OHOS::Ace::Framework 263 264 #include "v8_types.inl" 265 266 #endif