• 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 
IsUint8ClampedArray() const92 bool JsiValue::IsUint8ClampedArray() const
93 {
94     return (!GetHandle().IsEmpty()) && (GetHandle()->IsUint8ClampedArray());
95 }
96 
IsUndefined() const97 bool JsiValue::IsUndefined() const
98 {
99     if (GetHandle().IsEmpty()) {
100         return true;
101     } else {
102         return GetHandle()->IsUndefined();
103     }
104 }
105 
IsNull() const106 bool JsiValue::IsNull() const
107 {
108     if (GetHandle().IsEmpty()) {
109         return true;
110     } else {
111         return GetHandle()->IsNull();
112     }
113 }
114 
ToString() const115 std::string JsiValue::ToString() const
116 {
117     auto vm = GetEcmaVM();
118     panda::LocalScope scope(vm);
119     if (IsObject()) {
120         return JSON::Stringify(vm, GetLocalHandle())->ToString(vm)->ToString();
121     }
122     return GetHandle()->ToString(vm)->ToString();
123 }
124 
ToBoolean() const125 bool JsiValue::ToBoolean() const
126 {
127     return GetHandle()->BooleaValue();
128 }
129 
Undefined()130 JsiRef<JsiValue> JsiValue::Undefined()
131 {
132     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
133     return JsiRef<JsiValue>::Make(panda::JSValueRef::Undefined(runtime->GetEcmaVm()));
134 }
135 
Null()136 JsiRef<JsiValue> JsiValue::Null()
137 {
138     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
139     return JsiRef<JsiValue>::Make(panda::JSValueRef::Null(runtime->GetEcmaVm()));
140 }
141 
True()142 JsiRef<JsiValue> JsiValue::True()
143 {
144     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
145     return JsiRef<JsiValue>::Make(panda::JSValueRef::True(runtime->GetEcmaVm()));
146 }
147 
False()148 JsiRef<JsiValue> JsiValue::False()
149 {
150     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
151     return JsiRef<JsiValue>::Make(panda::JSValueRef::False(runtime->GetEcmaVm()));
152 }
153 
154 // -----------------------
155 // Implementation of JsiArray
156 // -----------------------
JsiArray()157 JsiArray::JsiArray() {}
JsiArray(const panda::CopyableGlobal<panda::ArrayRef> & val)158 JsiArray::JsiArray(const panda::CopyableGlobal<panda::ArrayRef>& val) : JsiType(val) {}
JsiArray(panda::Local<panda::ArrayRef> val)159 JsiArray::JsiArray(panda::Local<panda::ArrayRef> val) : JsiType(val) {}
160 
GetValueAt(size_t index) const161 JsiRef<JsiValue> JsiArray::GetValueAt(size_t index) const
162 {
163     return JsiRef<JsiValue>::Make(panda::ArrayRef::GetValueAt(GetEcmaVM(), GetLocalHandle(), index));
164 }
165 
SetValueAt(size_t index,JsiRef<JsiValue> value) const166 void JsiArray::SetValueAt(size_t index, JsiRef<JsiValue> value) const
167 {
168     panda::ArrayRef::SetValueAt(GetEcmaVM(), GetLocalHandle(), index, value.Get().GetLocalHandle());
169 }
170 
GetProperty(const char * prop) const171 JsiRef<JsiValue> JsiArray::GetProperty(const char* prop) const
172 {
173     auto vm = GetEcmaVM();
174     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
175     auto value = GetHandle()->Get(vm, stringRef);
176     auto func = JsiValue(value);
177     auto refValue =  JsiRef<JsiValue>(func);
178     return refValue;
179 }
180 
Length() const181 size_t JsiArray::Length() const
182 {
183     size_t length = -1;
184     JsiRef<JsiValue> propLength = GetProperty("length");
185     if (propLength->IsNumber()) {
186         length = propLength->ToNumber<int32_t>();
187     }
188     return length;
189 }
190 
IsArray() const191 bool JsiArray::IsArray() const
192 {
193     if (GetHandle().IsEmpty()) {
194         return false;
195     } else {
196         return GetHandle()->IsArray(GetEcmaVM());
197     }
198 }
199 
200 // -----------------------
201 // Implementation of JsiArrayBuffer
202 // -----------------------
JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val)203 JsiArrayBuffer::JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val) : JsiType(val) {}
JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef> & val)204 JsiArrayBuffer::JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef>& val) : JsiType(val) {}
205 
ByteLength() const206 int32_t JsiArrayBuffer::ByteLength() const
207 {
208     return GetHandle()->ByteLength(GetEcmaVM());
209 }
210 
GetBuffer() const211 void* JsiArrayBuffer::GetBuffer() const
212 {
213     return GetHandle()->GetBuffer();
214 }
215 
Detach() const216 void JsiArrayBuffer::Detach() const
217 {
218     GetHandle()->Detach(GetEcmaVM());
219 }
220 
IsDetach() const221 bool JsiArrayBuffer::IsDetach() const
222 {
223     return GetHandle()->IsDetach();
224 }
225 
226 // -----------------------
227 // Implementation of JsiArrayBufferRef
228 // -----------------------
JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val)229 JsiUint8ClampedArray::JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val) : JsiType(val) {}
JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef> & val)230 JsiUint8ClampedArray::JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef>& val) : JsiType(val)
231 {}
232 
GetArrayBuffer() const233 JsiRef<JsiArrayBuffer> JsiUint8ClampedArray::GetArrayBuffer() const
234 {
235     return JsiRef<JsiArrayBuffer>(JsiArrayBuffer(GetHandle()->GetArrayBuffer(GetEcmaVM())));
236 }
237 
238 // -----------------------
239 // Implementation of JsiObject
240 // -----------------------
JsiObject()241 JsiObject::JsiObject() : JsiType() {}
JsiObject(const panda::CopyableGlobal<panda::ObjectRef> & val)242 JsiObject::JsiObject(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiType(val) {}
JsiObject(panda::Local<panda::ObjectRef> val)243 JsiObject::JsiObject(panda::Local<panda::ObjectRef> val) : JsiType(val) {}
244 
IsUndefined() const245 bool JsiObject::IsUndefined() const
246 {
247     if (GetHandle().IsEmpty()) {
248         return true;
249     } else {
250         return GetHandle()->IsUndefined();
251     }
252 }
253 
GetPropertyNames() const254 JsiRef<JsiArray> JsiObject::GetPropertyNames() const
255 {
256     auto vm = GetEcmaVM();
257     return JsiRef<JsiArray>::Make(GetHandle()->GetOwnPropertyNames(vm));
258 }
259 
GetProperty(const char * prop) const260 JsiRef<JsiValue> JsiObject::GetProperty(const char* prop) const
261 {
262     auto vm = GetEcmaVM();
263     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
264     auto value = GetHandle()->Get(vm, stringRef);
265     auto func = JsiValue(value);
266     auto refValue =  JsiRef<JsiValue>(func);
267     return refValue;
268 }
269 
HasProperty(const char * prop) const270 bool JsiObject::HasProperty(const char* prop) const
271 {
272     auto vm = GetEcmaVM();
273     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
274     bool has = GetHandle()->Has(vm, stringRef);
275     return has;
276 }
277 
ToJsonObject(const char * value) const278 JsiRef<JsiValue> JsiObject::ToJsonObject(const char* value) const
279 {
280     auto vm = GetEcmaVM();
281     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(vm, value);
282     panda::Local<JSValueRef> result = JSON::Parse(vm, valueRef);
283     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
284     if (result.IsEmpty() || runtime->HasPendingException()) {
285         runtime->HandleUncaughtException();
286         return JsiRef<JsiValue>::Make(JSValueRef::Undefined(vm));
287     }
288 
289     return JsiRef<JsiValue>::Make(result);
290 }
291 
SetPropertyJsonObject(const char * prop,const char * value) const292 void JsiObject::SetPropertyJsonObject(const char* prop, const char* value) const
293 {
294     auto vm = GetEcmaVM();
295     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
296     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(GetEcmaVM(), value);
297     if (valueRef->IsString()) {
298         GetHandle()->Set(vm, stringRef, JSON::Parse(vm, valueRef));
299     }
300 }
301 
SetPropertyObject(const char * prop,JsiRef<JsiValue> value) const302 void JsiObject::SetPropertyObject(const char* prop, JsiRef<JsiValue> value) const
303 {
304     auto vm = GetEcmaVM();
305     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
306     GetHandle()->Set(vm, stringRef, value.Get().GetLocalHandle());
307 }
308 
309 // -----------------------
310 // Implementation of JsiFunction
311 // -----------------------
JsiFunction()312 JsiFunction::JsiFunction() {}
JsiFunction(const panda::CopyableGlobal<panda::FunctionRef> & val)313 JsiFunction::JsiFunction(const panda::CopyableGlobal<panda::FunctionRef>& val) : JsiType(val)
314 {
315 }
316 
JsiFunction(panda::Local<panda::FunctionRef> val)317 JsiFunction::JsiFunction(panda::Local<panda::FunctionRef> val) : JsiType(val)
318 {
319 }
320 
Call(JsiRef<JsiValue> thisVal,int argc,JsiRef<JsiValue> argv[]) const321 JsiRef<JsiValue> JsiFunction::Call(JsiRef<JsiValue> thisVal, int argc, JsiRef<JsiValue> argv[]) const
322 {
323     auto vm = GetEcmaVM();
324     LocalScope scope(vm);
325     std::vector<panda::Local<panda::JSValueRef>> arguments;
326     for (int i = 0; i < argc; ++i) {
327         arguments.emplace_back(argv[i].Get().GetLocalHandle());
328     }
329     auto thisObj = thisVal.Get().GetLocalHandle();
330     auto result = GetHandle()->Call(vm, thisObj, arguments.data(), argc);
331     JSNApi::ExecutePendingJob(vm);
332     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
333     if (result.IsEmpty() || runtime->HasPendingException()) {
334         runtime->HandleUncaughtException();
335         result = JSValueRef::Undefined(vm);
336     }
337     return JsiRef<JsiValue>::Make(result);
338 }
339 
New(JsiFunctionCallback func)340 panda::Local<panda::FunctionRef> JsiFunction::New(JsiFunctionCallback func)
341 {
342     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
343     return panda::FunctionRef::New(const_cast<EcmaVM*>(runtime->GetEcmaVm()), func);
344 }
345 
346 // -----------------------
347 // Implementation of JsiObjectTemplate
348 // -----------------------
JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef> & val)349 JsiObjTemplate::JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiObject(val) {}
JsiObjTemplate(panda::Local<panda::ObjectRef> val)350 JsiObjTemplate::JsiObjTemplate(panda::Local<panda::ObjectRef> val) : JsiObject(val) {}
351 
SetInternalFieldCount(int32_t count) const352 void JsiObjTemplate::SetInternalFieldCount(int32_t count) const
353 {
354     GetHandle()->SetNativePointerFieldCount(count);
355 }
356 
NewInstance() const357 JsiRef<JsiObject> JsiObjTemplate::NewInstance() const
358 {
359     auto instance = panda::ObjectRef::New(GetEcmaVM());
360     instance->SetNativePointerFieldCount(1);
361     return JsiRef<JsiObject>::Make(instance);
362 }
363 
New()364 panda::Local<panda::JSValueRef> JsiObjTemplate::New()
365 {
366     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
367     return panda::ObjectRef::New(runtime->GetEcmaVm());
368 }
369 
370 // -----------------------
371 // Implementation of JsiCallBackInfo
372 // -----------------------
JsiCallbackInfo(panda::JsiRuntimeCallInfo * info)373 JsiCallbackInfo::JsiCallbackInfo(panda::JsiRuntimeCallInfo* info) : info_(info) {}
374 
operator [](size_t index) const375 JsiRef<JsiValue> JsiCallbackInfo::operator[](size_t index) const
376 {
377     if (static_cast<int32_t>(index) < Length()) {
378         return JsiRef<JsiValue>::Make(info_->GetCallArgRef(index));
379     }
380     return JsiRef<JsiValue>::Make(panda::JSValueRef::Undefined(info_->GetVM()));
381 }
382 
This() const383 JsiRef<JsiObject> JsiCallbackInfo::This() const
384 {
385     auto obj = JsiObject { info_->GetThisRef() };
386     auto ref = JsiRef<JsiObject>(obj);
387     return ref;
388 }
389 
Length() const390 int JsiCallbackInfo::Length() const
391 {
392     return info_->GetArgsNumber();
393 }
394 
ReturnSelf() const395 void JsiCallbackInfo::ReturnSelf() const
396 {
397     panda::CopyableGlobal<panda::JSValueRef> thisObj(info_->GetVM(), info_->GetThisRef());
398     retVal_ = thisObj;
399 }
400 
401 // -----------------------
402 // Implementation of JsiString
403 // -----------------------
JsiString(const char * str)404 JsiString::JsiString(const char* str) : JsiValue(StringRef::NewFromUtf8(GetEcmaVM(), str)) {}
JsiString(JsiValue str)405 JsiString::JsiString(JsiValue str) : JsiValue(str) {}
406 
New(const char * str)407 JsiString JsiString::New(const char* str)
408 {
409     return JsiString(str);
410 }
411 
412 // -----------------------
413 // Implementation of JsiDate
414 // -----------------------
JsiDate(const panda::CopyableGlobal<panda::DateRef> & val)415 JsiDate::JsiDate(const panda::CopyableGlobal<panda::DateRef>& val) : JsiType(val) {}
JsiDate(panda::Local<panda::DateRef> val)416 JsiDate::JsiDate(panda::Local<panda::DateRef> val) : JsiType(val) {}
417 
New(double value)418 JsiRef<JsiValue> JsiDate::New(double value)
419 {
420     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
421     return JsiRef<JsiValue>::Make(panda::DateRef::New(runtime->GetEcmaVm(), value));
422 }
423 
424 } // namespace OHOS::Ace::Framework
425