• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_value.h"
17 
18 #include <iostream>
19 
20 // NOLINTNEXTLINE(readability-identifier-naming)
21 namespace OHOS::Ace::Framework {
ToInt32(shared_ptr<JsRuntime> runtime)22 int32_t ArkJSValue::ToInt32(shared_ptr<JsRuntime> runtime)
23 {
24     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
25     LocalScope scope(pandaRuntime->GetEcmaVm());
26     if (CheckException(pandaRuntime)) {
27         return 0;
28     }
29     return value_->Int32Value(pandaRuntime->GetEcmaVm());
30 }
31 
ToDouble(shared_ptr<JsRuntime> runtime)32 double ArkJSValue::ToDouble(shared_ptr<JsRuntime> runtime)
33 {
34     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
35     LocalScope scope(pandaRuntime->GetEcmaVm());
36     if (CheckException(pandaRuntime)) {
37         return 0;
38     }
39     Local<NumberRef> number = value_->ToNumber(pandaRuntime->GetEcmaVm());
40     if (!CheckException(pandaRuntime, number)) {
41         return number->Value();
42     }
43     return 0;
44 }
45 
ToString(shared_ptr<JsRuntime> runtime)46 std::string ArkJSValue::ToString(shared_ptr<JsRuntime> runtime)
47 {
48     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
49     LocalScope scope(pandaRuntime->GetEcmaVm());
50     if (CheckException(pandaRuntime)) {
51         return "";
52     }
53     Local<StringRef> string = value_->ToString(pandaRuntime->GetEcmaVm());
54     if (!CheckException(pandaRuntime, string)) {
55         return string->ToString();
56     }
57     return "";
58 }
59 
ToBoolean(shared_ptr<JsRuntime> runtime)60 bool ArkJSValue::ToBoolean(shared_ptr<JsRuntime> runtime)
61 {
62     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
63     LocalScope scope(pandaRuntime->GetEcmaVm());
64     return !CheckException(pandaRuntime) && value_->BooleaValue();
65 }
66 
IsUndefined(shared_ptr<JsRuntime> runtime)67 bool ArkJSValue::IsUndefined([[maybe_unused]] shared_ptr<JsRuntime> runtime)
68 {
69     return !value_.IsEmpty() && value_->IsUndefined();
70 }
71 
IsNull(shared_ptr<JsRuntime> runtime)72 bool ArkJSValue::IsNull([[maybe_unused]] shared_ptr<JsRuntime> runtime)
73 {
74     return !value_.IsEmpty() && value_->IsNull();
75 }
76 
IsBoolean(shared_ptr<JsRuntime> runtime)77 bool ArkJSValue::IsBoolean([[maybe_unused]] shared_ptr<JsRuntime> runtime)
78 {
79     return !value_.IsEmpty() && value_->IsBoolean();
80 }
81 
IsInt32(shared_ptr<JsRuntime> runtime)82 bool ArkJSValue::IsInt32([[maybe_unused]] shared_ptr<JsRuntime> runtime)
83 {
84     return !value_.IsEmpty() && value_->IsInt();
85 }
86 
WithinInt32(shared_ptr<JsRuntime> runtime)87 bool ArkJSValue::WithinInt32([[maybe_unused]] shared_ptr<JsRuntime> runtime)
88 {
89     return !value_.IsEmpty() && value_->WithinInt32();
90 }
91 
IsString(shared_ptr<JsRuntime> runtime)92 bool ArkJSValue::IsString([[maybe_unused]] shared_ptr<JsRuntime> runtime)
93 {
94     return !value_.IsEmpty() && value_->IsString();
95 }
96 
IsNumber(shared_ptr<JsRuntime> runtime)97 bool ArkJSValue::IsNumber([[maybe_unused]] shared_ptr<JsRuntime> runtime)
98 {
99     return !value_.IsEmpty() && value_->IsNumber();
100 }
101 
IsObject(shared_ptr<JsRuntime> runtime)102 bool ArkJSValue::IsObject([[maybe_unused]] shared_ptr<JsRuntime> runtime)
103 {
104     return !value_.IsEmpty() && value_->IsObject();
105 }
106 
IsArray(shared_ptr<JsRuntime> runtime)107 bool ArkJSValue::IsArray([[maybe_unused]] shared_ptr<JsRuntime> runtime)
108 {
109     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
110     return !value_.IsEmpty() && value_->IsArray(pandaRuntime->GetEcmaVm());
111 }
112 
IsFunction(shared_ptr<JsRuntime> runtime)113 bool ArkJSValue::IsFunction([[maybe_unused]] shared_ptr<JsRuntime> runtime)
114 {
115     return !value_.IsEmpty() && value_->IsFunction();
116 }
117 
118 // NOLINTNEXTLINE(performance-unnecessary-value-param)
IsException(shared_ptr<JsRuntime> runtime)119 bool ArkJSValue::IsException([[maybe_unused]] shared_ptr<JsRuntime> runtime)
120 {
121     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
122     return value_.IsEmpty() || pandaRuntime->HasPendingException();
123 }
124 
Call(shared_ptr<JsRuntime> runtime,shared_ptr<JsValue> thisObj,std::vector<shared_ptr<JsValue>> argv,int32_t argc)125 shared_ptr<JsValue> ArkJSValue::Call(shared_ptr<JsRuntime> runtime, shared_ptr<JsValue> thisObj,
126                                      std::vector<shared_ptr<JsValue>> argv, int32_t argc)
127 {
128     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
129     JSExecutionScope executionScope(pandaRuntime->GetEcmaVm());
130     LocalScope scope(pandaRuntime->GetEcmaVm());
131     if (!IsFunction(pandaRuntime)) {
132         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
133     }
134     std::vector<Local<JSValueRef>> arguments;
135     arguments.reserve(argc);
136     for (const shared_ptr<JsValue> &arg : argv) {
137         arguments.emplace_back(std::static_pointer_cast<ArkJSValue>(arg)->GetValue(pandaRuntime));
138     }
139     Local<JSValueRef> thisValue = std::static_pointer_cast<ArkJSValue>(thisObj)->GetValue(pandaRuntime);
140     Local<FunctionRef> function(GetValue(pandaRuntime));
141     Local<JSValueRef> result = function->Call(pandaRuntime->GetEcmaVm(), thisValue, arguments.data(), argc);
142     Local<ObjectRef> exception = JSNApi::GetUncaughtException(pandaRuntime->GetEcmaVm());
143     pandaRuntime->HandleUncaughtException();
144     if (!exception.IsEmpty() && !exception->IsHole()) {
145         result = JSValueRef::Undefined(pandaRuntime->GetEcmaVm());
146     }
147     return std::make_shared<ArkJSValue>(pandaRuntime, result);
148 }
149 
GetPropertyNames(shared_ptr<JsRuntime> runtime,shared_ptr<JsValue> & propName,int32_t & len)150 bool ArkJSValue::GetPropertyNames(shared_ptr<JsRuntime> runtime, shared_ptr<JsValue> &propName, int32_t &len)
151 {
152     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
153     LocalScope scope(pandaRuntime->GetEcmaVm());
154     if (CheckException(pandaRuntime)) {
155         return false;
156     }
157     Local<ObjectRef> obj = value_->ToObject(pandaRuntime->GetEcmaVm());
158     if (CheckException(pandaRuntime, obj)) {
159         return false;
160     }
161     Local<ArrayRef> names = obj->GetOwnPropertyNames(pandaRuntime->GetEcmaVm());
162     len = names->Length(pandaRuntime->GetEcmaVm());
163     if (!propName) {
164         propName = std::make_shared<ArkJSValue>(pandaRuntime, names);
165     } else {
166         std::static_pointer_cast<ArkJSValue>(propName)->SetValue(pandaRuntime, names);
167     }
168     return true;
169 }
170 
GetEnumerablePropertyNames(shared_ptr<JsRuntime> runtime,shared_ptr<JsValue> & propName,int32_t & len)171 bool ArkJSValue::GetEnumerablePropertyNames(shared_ptr<JsRuntime> runtime, shared_ptr<JsValue> &propName, int32_t &len)
172 {
173     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
174     LocalScope scope(pandaRuntime->GetEcmaVm());
175     if (CheckException(pandaRuntime)) {
176         return false;
177     }
178     Local<ObjectRef> obj = value_->ToObject(pandaRuntime->GetEcmaVm());
179     if (CheckException(pandaRuntime, obj)) {
180         return false;
181     }
182     Local<ArrayRef> names = obj->GetOwnEnumerablePropertyNames(pandaRuntime->GetEcmaVm());
183     len = names->Length(pandaRuntime->GetEcmaVm());
184     if (!propName) {
185         propName = std::make_shared<ArkJSValue>(pandaRuntime, names);
186     } else {
187         std::static_pointer_cast<ArkJSValue>(propName)->SetValue(pandaRuntime, names);
188     }
189     return true;
190 }
191 
GetProperty(shared_ptr<JsRuntime> runtime,int32_t idx)192 shared_ptr<JsValue> ArkJSValue::GetProperty(shared_ptr<JsRuntime> runtime, int32_t idx)
193 {
194     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
195     LocalScope scope(pandaRuntime->GetEcmaVm());
196     if (CheckException(pandaRuntime)) {
197         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
198     }
199     Local<ObjectRef> obj = value_->ToObject(pandaRuntime->GetEcmaVm());
200     if (CheckException(pandaRuntime, obj)) {
201         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
202     }
203     Local<JSValueRef> property = obj->Get(pandaRuntime->GetEcmaVm(), idx);
204     if (CheckException(pandaRuntime, property)) {
205         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
206     }
207     return std::make_shared<ArkJSValue>(pandaRuntime, property);
208 }
209 
GetProperty(shared_ptr<JsRuntime> runtime,const std::string & name)210 shared_ptr<JsValue> ArkJSValue::GetProperty(shared_ptr<JsRuntime> runtime, const std::string &name)
211 {
212     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
213     LocalScope scope(pandaRuntime->GetEcmaVm());
214     shared_ptr<JsValue> key = pandaRuntime->NewString(name);
215     return GetProperty(runtime, key);
216 }
217 
GetProperty(shared_ptr<JsRuntime> runtime,const shared_ptr<JsValue> & name)218 shared_ptr<JsValue> ArkJSValue::GetProperty(shared_ptr<JsRuntime> runtime, const shared_ptr<JsValue> &name)
219 {
220     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
221     LocalScope scope(pandaRuntime->GetEcmaVm());
222     if (CheckException(pandaRuntime)) {
223         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
224     }
225     Local<ObjectRef> obj = value_->ToObject(pandaRuntime->GetEcmaVm());
226     if (CheckException(pandaRuntime, obj)) {
227         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
228     }
229     Local<JSValueRef> key = std::static_pointer_cast<ArkJSValue>(name)->GetValue(pandaRuntime);
230     Local<JSValueRef> property = obj->Get(pandaRuntime->GetEcmaVm(), key);
231     if (CheckException(pandaRuntime, property)) {
232         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
233     }
234     return std::make_shared<ArkJSValue>(pandaRuntime, property);
235 }
236 
SetProperty(shared_ptr<JsRuntime> runtime,const std::string & name,const shared_ptr<JsValue> & value)237 bool ArkJSValue::SetProperty(shared_ptr<JsRuntime> runtime, const std::string &name, const shared_ptr<JsValue> &value)
238 {
239     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
240     LocalScope scope(pandaRuntime->GetEcmaVm());
241     shared_ptr<JsValue> key = pandaRuntime->NewString(name);
242     return SetProperty(runtime, key, value);
243 }
244 
SetProperty(shared_ptr<JsRuntime> runtime,const shared_ptr<JsValue> & name,const shared_ptr<JsValue> & value)245 bool ArkJSValue::SetProperty(shared_ptr<JsRuntime> runtime, const shared_ptr<JsValue> &name,
246                              const shared_ptr<JsValue> &value)
247 {
248     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
249     LocalScope scope(pandaRuntime->GetEcmaVm());
250     if (CheckException(pandaRuntime)) {
251         return false;
252     }
253     Local<ObjectRef> obj = value_->ToObject(pandaRuntime->GetEcmaVm());
254     if (CheckException(pandaRuntime, obj)) {
255         return false;
256     }
257     Local<JSValueRef> key = std::static_pointer_cast<ArkJSValue>(name)->GetValue(pandaRuntime);
258     Local<JSValueRef> value_ref = std::static_pointer_cast<ArkJSValue>(value)->GetValue(pandaRuntime);
259     return obj->Set(pandaRuntime->GetEcmaVm(), key, value_ref);
260 }
261 
SetAccessorProperty(shared_ptr<JsRuntime> runtime,const std::string & name,const shared_ptr<JsValue> & getter,const shared_ptr<JsValue> & setter)262 bool ArkJSValue::SetAccessorProperty(shared_ptr<JsRuntime> runtime, const std::string &name,
263                                      const shared_ptr<JsValue> &getter, const shared_ptr<JsValue> &setter)
264 {
265     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
266     LocalScope scope(pandaRuntime->GetEcmaVm());
267     shared_ptr<JsValue> key = pandaRuntime->NewString(name);
268     return SetAccessorProperty(runtime, key, getter, setter);
269 }
270 
SetAccessorProperty(shared_ptr<JsRuntime> runtime,const shared_ptr<JsValue> & name,const shared_ptr<JsValue> & getter,const shared_ptr<JsValue> & setter)271 bool ArkJSValue::SetAccessorProperty(shared_ptr<JsRuntime> runtime, const shared_ptr<JsValue> &name,
272                                      const shared_ptr<JsValue> &getter, const shared_ptr<JsValue> &setter)
273 {
274     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
275     LocalScope scope(pandaRuntime->GetEcmaVm());
276     if (CheckException(pandaRuntime)) {
277         return false;
278     }
279     Local<ObjectRef> obj = value_->ToObject(pandaRuntime->GetEcmaVm());
280     if (CheckException(pandaRuntime, obj)) {
281         return false;
282     }
283     Local<JSValueRef> key = std::static_pointer_cast<ArkJSValue>(name)->GetValue(pandaRuntime);
284     Local<JSValueRef> getterValue = std::static_pointer_cast<ArkJSValue>(getter)->GetValue(pandaRuntime);
285     Local<JSValueRef> setterValue = std::static_pointer_cast<ArkJSValue>(setter)->GetValue(pandaRuntime);
286     return obj->SetAccessorProperty(pandaRuntime->GetEcmaVm(), key, getterValue, setterValue);
287 }
288 
GetArrayLength(shared_ptr<JsRuntime> runtime)289 int32_t ArkJSValue::GetArrayLength(shared_ptr<JsRuntime> runtime)
290 {
291     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
292     LocalScope scope(pandaRuntime->GetEcmaVm());
293     if (CheckException(pandaRuntime)) {
294         return -1;
295     }
296     Local<ArrayRef> array(GetValue(pandaRuntime));
297     return array->Length(pandaRuntime->GetEcmaVm());
298 }
299 
GetElement(shared_ptr<JsRuntime> runtime,int32_t idx)300 shared_ptr<JsValue> ArkJSValue::GetElement(shared_ptr<JsRuntime> runtime, int32_t idx)
301 {
302     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
303     LocalScope scope(pandaRuntime->GetEcmaVm());
304     if (CheckException(pandaRuntime)) {
305         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
306     }
307     Local<ArrayRef> obj(GetValue(pandaRuntime));
308     if (CheckException(pandaRuntime, obj)) {
309         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
310     }
311     Local<JSValueRef> property = obj->Get(pandaRuntime->GetEcmaVm(), idx);
312     if (CheckException(pandaRuntime, property)) {
313         return std::make_shared<ArkJSValue>(pandaRuntime, JSValueRef::Undefined(pandaRuntime->GetEcmaVm()));
314     }
315     return std::make_shared<ArkJSValue>(pandaRuntime, property);
316 }
317 
GetJsonString(const shared_ptr<JsRuntime> & runtime)318 std::string ArkJSValue::GetJsonString(const shared_ptr<JsRuntime>& runtime)
319 {
320     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
321     LocalScope scope(pandaRuntime->GetEcmaVm());
322     auto stringify = panda::JSON::Stringify(pandaRuntime->GetEcmaVm(), GetValue(pandaRuntime));
323     if (CheckException(pandaRuntime, stringify)) {
324         return "";
325     }
326     auto valueStr = panda::Local<panda::StringRef>(stringify);
327     if (CheckException(pandaRuntime, valueStr)) {
328         return "";
329     }
330     return valueStr->ToString();
331 }
332 
CheckException(const shared_ptr<ArkJSRuntime> & runtime) const333 bool ArkJSValue::CheckException(const shared_ptr<ArkJSRuntime> &runtime) const
334 {
335     return value_.IsEmpty() || runtime->HasPendingException();
336 }
337 
CheckException(const shared_ptr<ArkJSRuntime> & runtime,const Local<JSValueRef> & value) const338 bool ArkJSValue::CheckException(const shared_ptr<ArkJSRuntime> &runtime, const Local<JSValueRef> &value) const
339 {
340     return value.IsEmpty() || runtime->HasPendingException();
341 }
342 }  // namespace OHOS::Ace::Framework