• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/jsi/jsi_types.h"
17 
18 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_runtime.h"
19 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
20 
21 namespace OHOS::Ace::Framework {
22 
23 // -----------------------
24 // Implementation of JsiValue
25 // -----------------------
JsiValue(const panda::CopyableGlobal<panda::JSValueRef> & val)26 JsiValue::JsiValue(const panda::CopyableGlobal<panda::JSValueRef>& val) : JsiType(val) {}
27 
JsiValue(panda::Local<panda::JSValueRef> val)28 JsiValue::JsiValue(panda::Local<panda::JSValueRef> val) : JsiType(val) {}
29 
IsEmpty() const30 bool JsiValue::IsEmpty() const
31 {
32     if (GetHandle().IsEmpty()) {
33         return true;
34     }
35     return GetHandle()->IsUndefined() || GetHandle()->IsNull();
36 }
37 
IsFunction() const38 bool JsiValue::IsFunction() const
39 {
40     if (GetHandle().IsEmpty()) {
41         return false;
42     } else {
43         return GetHandle()->IsFunction();
44     }
45 }
46 
IsNumber() const47 bool JsiValue::IsNumber() const
48 {
49     if (GetHandle().IsEmpty()) {
50         return false;
51     } else {
52         return GetHandle()->IsNumber();
53     }
54 }
55 
IsString() const56 bool JsiValue::IsString() const
57 {
58     if (GetHandle().IsEmpty()) {
59         return false;
60     } else {
61         return GetHandle()->IsString();
62     }
63 }
64 
IsBoolean() const65 bool JsiValue::IsBoolean() const
66 {
67     if (GetHandle().IsEmpty()) {
68         return false;
69     } else {
70         return GetHandle()->IsBoolean();
71     }
72 }
73 
IsObject() const74 bool JsiValue::IsObject() const
75 {
76     if (GetHandle().IsEmpty()) {
77         return false;
78     } else {
79         return GetHandle()->IsObject();
80     }
81 }
82 
IsArray() const83 bool JsiValue::IsArray() const
84 {
85     if (GetHandle().IsEmpty()) {
86         return false;
87     } else {
88         return GetHandle()->IsArray(GetEcmaVM());
89     }
90 }
91 
IsUndefined() const92 bool JsiValue::IsUndefined() const
93 {
94     if (GetHandle().IsEmpty()) {
95         return true;
96     } else {
97         return GetHandle()->IsUndefined();
98     }
99 }
100 
IsNull() const101 bool JsiValue::IsNull() const
102 {
103     if (GetHandle().IsEmpty()) {
104         return true;
105     } else {
106         return GetHandle()->IsNull();
107     }
108 }
109 
ToString() const110 std::string JsiValue::ToString() const
111 {
112     auto vm = GetEcmaVM();
113     panda::LocalScope scope(vm);
114     if (IsObject()) {
115         return JSON::Stringify(vm, GetLocalHandle())->ToString(vm)->ToString();
116     }
117     return GetHandle()->ToString(vm)->ToString();
118 }
119 
ToBoolean() const120 bool JsiValue::ToBoolean() const
121 {
122     return GetHandle()->BooleaValue();
123 }
124 
125 // -----------------------
126 // Implementation of JsiArray
127 // -----------------------
JsiArray()128 JsiArray::JsiArray() {}
JsiArray(const panda::CopyableGlobal<panda::ArrayRef> & val)129 JsiArray::JsiArray(const panda::CopyableGlobal<panda::ArrayRef>& val) : JsiType(val) {}
JsiArray(panda::Local<panda::ArrayRef> val)130 JsiArray::JsiArray(panda::Local<panda::ArrayRef> val) : JsiType(val) {}
131 
GetValueAt(size_t index) const132 JsiRef<JsiValue> JsiArray::GetValueAt(size_t index) const
133 {
134     return JsiRef<JsiValue>::Make(panda::ArrayRef::GetValueAt(GetEcmaVM(), GetLocalHandle(), index));
135 }
136 
SetValueAt(size_t index,JsiRef<JsiValue> value) const137 void JsiArray::SetValueAt(size_t index, JsiRef<JsiValue> value) const
138 {
139     panda::ArrayRef::SetValueAt(GetEcmaVM(), GetLocalHandle(), index, value.Get().GetLocalHandle());
140 }
141 
GetProperty(const char * prop) const142 JsiRef<JsiValue> JsiArray::GetProperty(const char* prop) const
143 {
144     auto vm = GetEcmaVM();
145     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
146     auto value = GetHandle()->Get(vm, stringRef);
147     auto func = JsiValue(value);
148     auto refValue =  JsiRef<JsiValue>(func);
149     return refValue;
150 }
151 
Length() const152 size_t JsiArray::Length() const
153 {
154     size_t length = -1;
155     JsiRef<JsiValue> propLength = GetProperty("length");
156     if (propLength->IsNumber()) {
157         length = propLength->ToNumber<int32_t>();
158     }
159     return length;
160 }
161 
IsArray() const162 bool JsiArray::IsArray() const
163 {
164     if (GetHandle().IsEmpty()) {
165         return false;
166     } else {
167         return GetHandle()->IsArray(GetEcmaVM());
168     }
169 }
170 
171 // -----------------------
172 // Implementation of JsiObject
173 // -----------------------
JsiObject()174 JsiObject::JsiObject() : JsiType() {}
JsiObject(const panda::CopyableGlobal<panda::ObjectRef> & val)175 JsiObject::JsiObject(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiType(val) {}
JsiObject(panda::Local<panda::ObjectRef> val)176 JsiObject::JsiObject(panda::Local<panda::ObjectRef> val) : JsiType(val) {}
177 
IsUndefined() const178 bool JsiObject::IsUndefined() const
179 {
180     if (GetHandle().IsEmpty()) {
181         return true;
182     } else {
183         return GetHandle()->IsUndefined();
184     }
185 }
186 
GetPropertyNames() const187 JsiRef<JsiArray> JsiObject::GetPropertyNames() const
188 {
189     auto vm = GetEcmaVM();
190     return JsiRef<JsiArray>::Make(GetHandle()->GetOwnPropertyNames(vm));
191 }
192 
GetProperty(const char * prop) const193 JsiRef<JsiValue> JsiObject::GetProperty(const char* prop) const
194 {
195     auto vm = GetEcmaVM();
196     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
197     auto value = GetHandle()->Get(vm, stringRef);
198     auto func = JsiValue(value);
199     auto refValue =  JsiRef<JsiValue>(func);
200     return refValue;
201 }
202 
ToJsonObject(const char * value) const203 JsiRef<JsiValue> JsiObject::ToJsonObject(const char* value) const
204 {
205     auto vm = GetEcmaVM();
206     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(vm, value);
207     auto refValue = JsiRef<JsiValue>::Make(JSON::Parse(vm, valueRef));
208     return refValue;
209 }
210 
SetPropertyJsonObject(const char * prop,const char * value) const211 void JsiObject::SetPropertyJsonObject(const char* prop, const char* value) const
212 {
213     auto vm = GetEcmaVM();
214     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
215     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(GetEcmaVM(), value);
216     if (valueRef->IsString()) {
217         GetHandle()->Set(vm, stringRef, JSON::Parse(vm, valueRef));
218     }
219 }
220 
SetPropertyObject(const char * prop,JsiRef<JsiValue> value) const221 void JsiObject::SetPropertyObject(const char* prop, JsiRef<JsiValue> value) const
222 {
223     auto vm = GetEcmaVM();
224     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
225     GetHandle()->Set(vm, stringRef, value.Get().GetLocalHandle());
226 }
227 
228 // -----------------------
229 // Implementation of JsiFunction
230 // -----------------------
JsiFunction()231 JsiFunction::JsiFunction() {}
JsiFunction(const panda::CopyableGlobal<panda::FunctionRef> & val)232 JsiFunction::JsiFunction(const panda::CopyableGlobal<panda::FunctionRef>& val) : JsiType(val)
233 {
234 }
235 
JsiFunction(panda::Local<panda::FunctionRef> val)236 JsiFunction::JsiFunction(panda::Local<panda::FunctionRef> val) : JsiType(val)
237 {
238 }
239 
Call(JsiRef<JsiValue> thisVal,int argc,JsiRef<JsiValue> argv[]) const240 JsiRef<JsiValue> JsiFunction::Call(JsiRef<JsiValue> thisVal, int argc, JsiRef<JsiValue> argv[]) const
241 {
242     auto vm = GetEcmaVM();
243     LocalScope scope(vm);
244     std::vector<panda::Local<panda::JSValueRef>> arguments;
245     for (int i = 0; i < argc; ++i) {
246         arguments.emplace_back(argv[i].Get().GetLocalHandle());
247     }
248     auto thisObj = thisVal.Get().GetLocalHandle();
249     auto result = GetHandle()->Call(vm, thisObj, arguments.data(), argc);
250     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
251     if (result.IsEmpty() || runtime->HasPendingException()) {
252         runtime->HandleUncaughtException();
253         result = JSValueRef::Undefined(vm);
254     }
255     return JsiRef<JsiValue>::Make(result);
256 }
257 
New(JsiFunctionCallback func)258 panda::Local<panda::FunctionRef> JsiFunction::New(JsiFunctionCallback func)
259 {
260     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
261     return panda::FunctionRef::New(const_cast<EcmaVM*>(runtime->GetEcmaVm()), func);
262 }
263 
264 // -----------------------
265 // Implementation of JsiObjectTemplate
266 // -----------------------
JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef> & val)267 JsiObjTemplate::JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiObject(val) {}
JsiObjTemplate(panda::Local<panda::ObjectRef> val)268 JsiObjTemplate::JsiObjTemplate(panda::Local<panda::ObjectRef> val) : JsiObject(val) {}
269 
SetInternalFieldCount(int32_t count) const270 void JsiObjTemplate::SetInternalFieldCount(int32_t count) const
271 {
272     GetHandle()->SetNativePointerFieldCount(count);
273 }
274 
NewInstance() const275 JsiRef<JsiObject> JsiObjTemplate::NewInstance() const
276 {
277     auto instance = panda::ObjectRef::New(GetEcmaVM());
278     instance->SetNativePointerFieldCount(1);
279     return JsiRef<JsiObject>::Make(instance);
280 }
281 
New()282 panda::Local<panda::JSValueRef> JsiObjTemplate::New()
283 {
284     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
285     return panda::ObjectRef::New(runtime->GetEcmaVm());
286 }
287 
288 // -----------------------
289 // Implementation of JsiCallBackInfo
290 // -----------------------
JsiCallbackInfo(panda::JsiRuntimeCallInfo * info)291 JsiCallbackInfo::JsiCallbackInfo(panda::JsiRuntimeCallInfo* info) : info_(info) {}
292 
operator [](size_t index) const293 JsiRef<JsiValue> JsiCallbackInfo::operator[](size_t index) const
294 {
295     if (static_cast<int32_t>(index) < Length()) {
296         return JsiRef<JsiValue>::Make(info_->GetCallArgRef(index));
297     }
298     return JsiRef<JsiValue>::Make(panda::JSValueRef::Undefined(info_->GetVM()));
299 }
300 
This() const301 JsiRef<JsiObject> JsiCallbackInfo::This() const
302 {
303     auto obj = JsiObject { info_->GetThisRef() };
304     auto ref = JsiRef<JsiObject>(obj);
305     return ref;
306 }
307 
Length() const308 int JsiCallbackInfo::Length() const
309 {
310     return info_->GetArgsNumber();
311 }
312 
ReturnSelf() const313 void JsiCallbackInfo::ReturnSelf() const
314 {
315     panda::CopyableGlobal<panda::JSValueRef> thisObj(info_->GetVM(), info_->GetThisRef());
316     retVal_ = thisObj;
317 }
318 
319 // -----------------------
320 // Implementation of JsiString
321 // -----------------------
JsiString(const char * str)322 JsiString::JsiString(const char* str) : JsiValue(StringRef::NewFromUtf8(GetEcmaVM(), str)) {}
JsiString(JsiValue str)323 JsiString::JsiString(JsiValue str) : JsiValue(str) {}
324 
New(const char * str)325 JsiString JsiString::New(const char* str)
326 {
327     return JsiString(str);
328 }
329 
330 
331 } // namespace OHOS::Ace::Framework
332