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 #include "frameworks/bridge/declarative_frontend/engine/v8/v8_types.h"
17
18 #include "frameworks/bridge/declarative_frontend/engine/v8/v8_ref.h"
19 #include "frameworks/bridge/declarative_frontend/engine/v8/v8_value_conversions.h"
20
21 namespace OHOS::Ace::Framework {
22
V8Value()23 V8Value::V8Value() : V8Type(v8::Undefined(v8::Isolate::GetCurrent())) {}
24
V8Value(v8::Local<v8::Value> val)25 V8Value::V8Value(v8::Local<v8::Value> val) : V8Type(val) {}
26
IsFunction() const27 bool V8Value::IsFunction() const
28 {
29 return GetHandle()->IsFunction();
30 }
IsNumber() const31 bool V8Value::IsNumber() const
32 {
33 return GetHandle()->IsNumber();
34 }
IsString() const35 bool V8Value::IsString() const
36 {
37 return GetHandle()->IsString();
38 }
IsBoolean() const39 bool V8Value::IsBoolean() const
40 {
41 return GetHandle()->IsBoolean();
42 }
IsObject() const43 bool V8Value::IsObject() const
44 {
45 return GetHandle()->IsObject();
46 }
IsArray() const47 bool V8Value::IsArray() const
48 {
49 return GetHandle()->IsArray();
50 }
IsUndefined() const51 bool V8Value::IsUndefined() const
52 {
53 return GetHandle()->IsUndefined();
54 }
55
IsNull() const56 bool V8Value::IsNull() const
57 {
58 return GetHandle()->IsNull();
59 }
60
ToString() const61 std::string V8Value::ToString() const
62 {
63 if (!IsObject()) {
64 return V8Utils::ScopedString(GetHandle());
65 }
66
67 v8::Isolate* isolate = v8::Isolate::GetCurrent();
68 v8::HandleScope scp(isolate);
69 auto context = isolate->GetCurrentContext();
70 return V8Utils::ScopedString(v8::JSON::Stringify(context, GetHandle()).ToLocalChecked());
71 }
72
ToBoolean() const73 bool V8Value::ToBoolean() const
74 {
75 return GetHandle()->BooleanValue(v8::Isolate::GetCurrent());
76 }
77
GetPropertyNames() const78 V8Ref<V8Array> V8Object::GetPropertyNames() const
79 {
80 v8::Isolate* isolate = v8::Isolate::GetCurrent();
81 v8::HandleScope scp(isolate);
82 auto context = isolate->GetCurrentContext();
83 v8::Local<v8::Array> val = GetHandle()->GetPropertyNames(context).ToLocalChecked();
84 V8Ref<V8Array> result = V8Ref<V8Array>::Make(val);
85 return result;
86 }
87
GetProperty(const char * prop) const88 V8Ref<V8Value> V8Object::GetProperty(const char* prop) const
89 {
90 v8::Isolate* isolate = v8::Isolate::GetCurrent();
91 v8::HandleScope scp(isolate);
92 auto context = isolate->GetCurrentContext();
93 v8::Local<v8::Value> val =
94 GetHandle()->Get(context, V8ValueConvertor::toV8Value<std::string>(prop)).ToLocalChecked();
95 V8Ref<V8Value> result = V8Ref<V8Value>::Make(val);
96 return result;
97 }
98
GetValueAt(size_t index) const99 V8Ref<V8Value> V8Object::GetValueAt(size_t index) const
100 {
101 v8::Isolate* isolate = v8::Isolate::GetCurrent();
102 v8::HandleScope scp(isolate);
103 auto context = isolate->GetCurrentContext();
104 v8::MaybeLocal<v8::Value> val = GetHandle()->Get(context, index);
105 if (val.IsEmpty()) {
106 return V8Ref<V8Value>();
107 }
108
109 return V8Ref<V8Value>::Make(val.ToLocalChecked());
110 }
111
SetValueAt(size_t index,V8Ref<V8Value> value) const112 void V8Object::SetValueAt(size_t index, V8Ref<V8Value> value) const
113 {
114 v8::Isolate* isolate = v8::Isolate::GetCurrent();
115 v8::HandleScope scp(isolate);
116 auto context = isolate->GetCurrentContext();
117 GetHandle()->Set(context, index, value->GetHandle()).ToChecked();
118 }
119
SetPropertyJsonObject(const char * prop,const char * value) const120 void V8Object::SetPropertyJsonObject(const char* prop, const char* value) const
121 {
122 v8::Isolate* isolate = v8::Isolate::GetCurrent();
123 v8::HandleScope scp(isolate);
124 auto context = isolate->GetCurrentContext();
125 v8::Local<v8::String> objStr = v8::String::NewFromUtf8(isolate, value).ToLocalChecked();
126 v8::Local<v8::Value> obj = v8::JSON::Parse(context, objStr).ToLocalChecked();
127 GetHandle()->Set(context, V8ValueConvertor::toV8Value<std::string>(prop), obj).ToChecked();
128 }
129
SetPropertyObject(const char * prop,V8Ref<V8Value> value) const130 void V8Object::SetPropertyObject(const char* prop, V8Ref<V8Value> value) const
131 {
132 v8::Isolate* isolate = v8::Isolate::GetCurrent();
133 v8::HandleScope scp(isolate);
134 auto context = isolate->GetCurrentContext();
135 GetHandle()->Set(context, V8ValueConvertor::toV8Value<std::string>(prop), value->GetHandle()).ToChecked();
136 }
137
V8Object()138 V8Object::V8Object() : V8Type() {}
V8Object(v8::Local<v8::Object> obj)139 V8Object::V8Object(v8::Local<v8::Object> obj) : V8Type(obj) {}
140
V8Function()141 V8Function::V8Function() {}
V8Function(v8::Local<v8::Function> obj)142 V8Function::V8Function(v8::Local<v8::Function> obj) : V8Type(obj)
143 {
144 isolate_ = v8::Isolate::GetCurrent();
145 ctx_.Reset(isolate_, isolate_->GetCurrentContext());
146 }
147
Call(V8Ref<V8Value> thisVal,int argc,V8Ref<V8Value> argv[]) const148 V8Ref<V8Value> V8Function::Call(V8Ref<V8Value> thisVal, int argc, V8Ref<V8Value> argv[]) const
149 {
150 std::vector<v8::Local<v8::Value>> localArgv;
151 v8::Isolate::Scope iScp(isolate_);
152 v8::HandleScope scp(isolate_);
153 auto context = ctx_.Get(isolate_);
154 v8::Context::Scope ctxScp(context);
155
156 for (int i = 0; i < argc; ++i) {
157 localArgv.push_back(argv[i].Get().GetHandle());
158 }
159
160 v8::TryCatch tryCatch(isolate_);
161 v8::Local<v8::Value> result;
162 v8::Local<v8::Value> jsThis = v8::Undefined(isolate_);
163 if (!thisVal.IsEmpty()) {
164 jsThis = thisVal.Get().GetHandle();
165 }
166
167 bool success = GetHandle()->Call(context, jsThis, argc, localArgv.data()).ToLocal(&result);
168 if (!success) {
169 V8Utils::JsStdDumpErrorAce(isolate_, &tryCatch);
170 }
171
172 if (result.IsEmpty()) {
173 return V8Ref<V8Value>();
174 }
175
176 return V8Ref<V8Value>::Make(result);
177 }
178
New(FunctionCallback func)179 v8::Local<v8::Function> V8Function::New(FunctionCallback func)
180 {
181 auto isolate = v8::Isolate::GetCurrent();
182 v8::HandleScope scp(isolate);
183 auto context = isolate->GetCurrentContext();
184 return v8::Function::New(context, func).ToLocalChecked();
185 }
186
V8Array()187 V8Array::V8Array() {}
V8Array(v8::Local<v8::Array> arr)188 V8Array::V8Array(v8::Local<v8::Array> arr) : V8Type(arr) {}
189
GetValueAt(size_t index) const190 V8Ref<V8Value> V8Array::GetValueAt(size_t index) const
191 {
192 v8::Isolate* isolate = v8::Isolate::GetCurrent();
193 v8::HandleScope scp(isolate);
194 auto context = isolate->GetCurrentContext();
195 v8::MaybeLocal<v8::Value> val = GetHandle()->Get(context, index);
196 if (val.IsEmpty()) {
197 return V8Ref<V8Value>();
198 }
199
200 return V8Ref<V8Value>::Make(val.ToLocalChecked());
201 }
202
SetValueAt(size_t index,V8Ref<V8Value> value) const203 void V8Array::SetValueAt(size_t index, V8Ref<V8Value> value) const
204 {
205 v8::Isolate* isolate = v8::Isolate::GetCurrent();
206 v8::HandleScope scp(isolate);
207 auto context = isolate->GetCurrentContext();
208 GetHandle()->Set(context, index, value->GetHandle()).ToChecked();
209 }
210
Length() const211 size_t V8Array::Length() const
212 {
213 return GetHandle()->Length();
214 }
215
V8String(const char * str)216 V8String::V8String(const char* str) : V8Type(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str).ToLocalChecked())
217 {
218 }
New(const char * str)219 V8String V8String::New(const char* str)
220 {
221 return V8String(str);
222 }
223
V8CallbackInfo(const v8::FunctionCallbackInfo<v8::Value> & info)224 V8CallbackInfo::V8CallbackInfo(const v8::FunctionCallbackInfo<v8::Value>& info) : info_(info)
225 {
226 isolate_ = info.GetIsolate();
227 ctx_.Reset(isolate_, isolate_->GetCurrentContext());
228 ctx_.SetWeak();
229 }
230
operator [](size_t index) const231 V8Ref<V8Value> V8CallbackInfo::operator[](size_t index) const
232 {
233 return V8Ref<V8Value>::Make(info_[index]);
234 }
235
This() const236 V8Ref<V8Object> V8CallbackInfo::This() const
237 {
238 return V8Ref<V8Object>::Make(info_.This());
239 }
240
ReturnSelf() const241 void V8CallbackInfo::ReturnSelf() const
242 {
243 return info_.GetReturnValue().Set(info_.This());
244 }
245
Length() const246 int V8CallbackInfo::Length() const
247 {
248 return info_.Length();
249 }
250
SetInternalFieldCount(int count) const251 void V8ObjTemplate::SetInternalFieldCount(int count) const
252 {
253 GetHandle()->SetInternalFieldCount(count);
254 }
255
NewInstance() const256 V8Ref<V8Object> V8ObjTemplate::NewInstance() const
257 {
258 v8::Isolate* isolate = v8::Isolate::GetCurrent();
259 v8::HandleScope scp(isolate);
260 auto context = isolate->GetCurrentContext();
261 v8::MaybeLocal<v8::Object> val = GetHandle()->NewInstance(context);
262 if (val.IsEmpty()) {
263 return V8Ref<V8Object>();
264 }
265 return V8Ref<V8Object>::Make(val.ToLocalChecked());
266 }
267
New()268 v8::Local<v8::ObjectTemplate> V8ObjTemplate::New()
269 {
270 auto isolate = v8::Isolate::GetCurrent();
271 return v8::ObjectTemplate::New(isolate);
272 }
273
274 } // namespace OHOS::Ace::Framework