• 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 "base/log/ace_performance_monitor.h"
19 #include "frameworks/bridge/declarative_frontend/engine/jsi/js_ui_index.h"
20 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_runtime.h"
21 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
22 
23 namespace OHOS::Ace::Framework {
24 
25 // -----------------------
26 // Implementation of JsiValue
27 // -----------------------
JsiValue(const panda::CopyableGlobal<panda::JSValueRef> & val)28 JsiValue::JsiValue(const panda::CopyableGlobal<panda::JSValueRef>& val) : JsiType(val) {}
29 
JsiValue(panda::Local<panda::JSValueRef> val)30 JsiValue::JsiValue(panda::Local<panda::JSValueRef> val) : JsiType(val) {}
31 
JsiValue(const EcmaVM * vm,panda::Local<panda::JSValueRef> val)32 JsiValue::JsiValue(const EcmaVM *vm, panda::Local<panda::JSValueRef> val) : JsiType(vm, val) {}
33 
IsEmpty() const34 bool JsiValue::IsEmpty() const
35 {
36     if (GetHandle().IsEmpty()) {
37         return true;
38     }
39     return GetHandle()->IsUndefined() || GetHandle()->IsNull();
40 }
41 
IsFunction() const42 bool JsiValue::IsFunction() const
43 {
44     if (GetHandle().IsEmpty()) {
45         return false;
46     } else {
47         return GetHandle()->IsFunction(GetEcmaVM());
48     }
49 }
50 
IsNumber() const51 bool JsiValue::IsNumber() const
52 {
53     if (GetHandle().IsEmpty()) {
54         return false;
55     } else {
56         return GetHandle()->IsNumber();
57     }
58 }
59 
IsString() const60 bool JsiValue::IsString() const
61 {
62     if (GetHandle().IsEmpty()) {
63         return false;
64     } else {
65         return GetHandle()->IsString(GetEcmaVM());
66     }
67 }
68 
IsBoolean() const69 bool JsiValue::IsBoolean() const
70 {
71     if (GetHandle().IsEmpty()) {
72         return false;
73     } else {
74         return GetHandle()->IsBoolean();
75     }
76 }
77 
IsObject() const78 bool JsiValue::IsObject() const
79 {
80     if (GetHandle().IsEmpty()) {
81         return false;
82     } else {
83         return GetHandle()->IsObject(GetEcmaVM());
84     }
85 }
86 
IsArray() const87 bool JsiValue::IsArray() const
88 {
89     if (GetHandle().IsEmpty()) {
90         return false;
91     } else {
92         return GetHandle()->IsArray(GetEcmaVM());
93     }
94 }
95 
IsArrayBuffer() const96 bool JsiValue::IsArrayBuffer() const
97 {
98     if (GetHandle().IsEmpty()) {
99         return false;
100     } else {
101         return GetHandle()->IsArrayBuffer(GetEcmaVM());
102     }
103 }
104 
IsUint8ClampedArray() const105 bool JsiValue::IsUint8ClampedArray() const
106 {
107     return (!GetHandle().IsEmpty()) && (GetHandle()->IsUint8ClampedArray(GetEcmaVM()));
108 }
109 
IsUndefined() const110 bool JsiValue::IsUndefined() const
111 {
112     if (GetHandle().IsEmpty()) {
113         return true;
114     } else {
115         return GetHandle()->IsUndefined();
116     }
117 }
118 
IsNull() const119 bool JsiValue::IsNull() const
120 {
121     if (GetHandle().IsEmpty()) {
122         return true;
123     } else {
124         return GetHandle()->IsNull();
125     }
126 }
127 
IsDate() const128 bool JsiValue::IsDate() const
129 {
130     if (GetHandle().IsEmpty()) {
131         return false;
132     } else {
133         return GetHandle()->IsDate(GetEcmaVM());
134     }
135 }
136 
ToString() const137 std::string JsiValue::ToString() const
138 {
139     auto vm = GetEcmaVM();
140     panda::LocalScope scope(vm);
141     if (IsObject()) {
142         return JSON::Stringify(vm, GetLocalHandle())->ToString(vm)->ToString(vm);
143     }
144     return GetHandle()->ToString(vm)->ToString(vm);
145 }
146 
ToU16String() const147 std::u16string JsiValue::ToU16String() const
148 {
149     auto vm = GetEcmaVM();
150     Local<StringRef> stringRef;
151     panda::LocalScope scope(vm);
152     if (IsObject()) {
153         stringRef = JSON::Stringify(vm, GetLocalHandle())->ToString(vm);
154     } else {
155         stringRef = GetHandle()->ToString(vm);
156     }
157     auto utf16Len = stringRef->Length(vm);
158     std::unique_ptr<char16_t[]> pBuf16 = std::make_unique<char16_t[]>(utf16Len);
159     char16_t *buf16 = pBuf16.get();
160     auto resultLen = stringRef->WriteUtf16(vm, buf16, utf16Len);
161     return std::u16string(buf16, resultLen);
162 }
163 
ToBoolean() const164 bool JsiValue::ToBoolean() const
165 {
166     if (SystemProperties::DetectJsObjTypeConvertion() && !IsBoolean()) {
167         LOGF_ABORT("bad call to ToBoolean.");
168     }
169     return GetHandle()->BooleaValue(GetEcmaVM());
170 }
171 
Undefined()172 JsiRef<JsiValue> JsiValue::Undefined()
173 {
174     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
175     return JsiRef<JsiValue>::Make(panda::JSValueRef::Undefined(runtime->GetEcmaVm()));
176 }
177 
Null()178 JsiRef<JsiValue> JsiValue::Null()
179 {
180     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
181     return JsiRef<JsiValue>::Make(panda::JSValueRef::Null(runtime->GetEcmaVm()));
182 }
183 
True()184 JsiRef<JsiValue> JsiValue::True()
185 {
186     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
187     return JsiRef<JsiValue>::Make(panda::JSValueRef::True(runtime->GetEcmaVm()));
188 }
189 
False()190 JsiRef<JsiValue> JsiValue::False()
191 {
192     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
193     return JsiRef<JsiValue>::Make(panda::JSValueRef::False(runtime->GetEcmaVm()));
194 }
195 
196 // -----------------------
197 // Implementation of JsiArray
198 // -----------------------
JsiArray()199 JsiArray::JsiArray() {}
JsiArray(const panda::CopyableGlobal<panda::ArrayRef> & val)200 JsiArray::JsiArray(const panda::CopyableGlobal<panda::ArrayRef>& val) : JsiType(val) {}
JsiArray(panda::Local<panda::ArrayRef> val)201 JsiArray::JsiArray(panda::Local<panda::ArrayRef> val) : JsiType(val) {}
JsiArray(const EcmaVM * vm,panda::Local<panda::ArrayRef> val)202 JsiArray::JsiArray(const EcmaVM *vm, panda::Local<panda::ArrayRef> val) : JsiType(vm, val) {}
203 
GetValueAt(size_t index) const204 JsiRef<JsiValue> JsiArray::GetValueAt(size_t index) const
205 {
206     return JsiRef<JsiValue>::FastMake(GetEcmaVM(), panda::ArrayRef::GetValueAt(GetEcmaVM(), GetLocalHandle(), index));
207 }
208 
SetValueAt(size_t index,JsiRef<JsiValue> value) const209 void JsiArray::SetValueAt(size_t index, JsiRef<JsiValue> value) const
210 {
211     panda::ArrayRef::SetValueAt(GetEcmaVM(), GetLocalHandle(), index, value.Get().GetLocalHandle());
212 }
213 
GetProperty(const char * prop) const214 JsiRef<JsiValue> JsiArray::GetProperty(const char* prop) const
215 {
216     auto vm = GetEcmaVM();
217     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
218     auto value = GetHandle()->Get(vm, stringRef);
219     auto func = JsiValue(vm, value);
220     auto refValue =  JsiRef<JsiValue>(func);
221     return refValue;
222 }
223 
GetProperty(int32_t propertyIndex) const224 JsiRef<JsiValue> JsiArray::GetProperty(int32_t propertyIndex) const
225 {
226     auto vm = GetEcmaVM();
227     auto stringRef = panda::ExternalStringCache::GetCachedString(vm, propertyIndex);
228     auto value = GetHandle()->Get(vm, stringRef);
229     auto func = JsiValue(vm, value);
230     auto refValue = JsiRef<JsiValue>(func);
231     return refValue;
232 }
233 
Length() const234 size_t JsiArray::Length() const
235 {
236     size_t length = -1;
237     JsiRef<JsiValue> propLength = GetProperty(static_cast<int32_t>(ArkUIIndex::LENGTH));
238     if (propLength->IsNumber()) {
239         length = propLength->ToNumber<int32_t>();
240     }
241     return length;
242 }
243 
SetLength(size_t length) const244 void JsiArray::SetLength(size_t length) const
245 {
246     auto stringRef = panda::StringRef::NewFromUtf8(GetEcmaVM(), "length");
247     GetHandle()->Set(GetEcmaVM(), stringRef, JsiValueConvertor::toJsiValueWithVM<size_t>(GetEcmaVM(), length));
248 }
249 
IsArray() const250 bool JsiArray::IsArray() const
251 {
252     if (GetHandle().IsEmpty()) {
253         return false;
254     } else {
255         return GetHandle()->IsArray(GetEcmaVM());
256     }
257 }
258 
259 // -----------------------
260 // Implementation of JsiArrayBuffer
261 // -----------------------
JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val)262 JsiArrayBuffer::JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val) : JsiType(val) {}
JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef> & val)263 JsiArrayBuffer::JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef>& val) : JsiType(val) {}
264 
ByteLength() const265 int32_t JsiArrayBuffer::ByteLength() const
266 {
267     return GetHandle()->ByteLength(GetEcmaVM());
268 }
269 
GetBuffer() const270 void* JsiArrayBuffer::GetBuffer() const
271 {
272     return GetHandle()->GetBuffer(GetEcmaVM());
273 }
274 
Detach() const275 void JsiArrayBuffer::Detach() const
276 {
277     GetHandle()->Detach(GetEcmaVM());
278 }
279 
IsDetach() const280 bool JsiArrayBuffer::IsDetach() const
281 {
282     return GetHandle()->IsDetach(GetEcmaVM());
283 }
284 
285 // -----------------------
286 // Implementation of JsiArrayBufferRef
287 // -----------------------
JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val)288 JsiUint8ClampedArray::JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val) : JsiType(val) {}
JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef> & val)289 JsiUint8ClampedArray::JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef>& val) : JsiType(val)
290 {}
291 
GetArrayBuffer() const292 JsiRef<JsiArrayBuffer> JsiUint8ClampedArray::GetArrayBuffer() const
293 {
294     return JsiRef<JsiArrayBuffer>(JsiArrayBuffer(GetHandle()->GetArrayBuffer(GetEcmaVM())));
295 }
296 
297 // -----------------------
298 // Implementation of JsiObject
299 // -----------------------
JsiObject()300 JsiObject::JsiObject() : JsiType() {}
JsiObject(const panda::CopyableGlobal<panda::ObjectRef> & val)301 JsiObject::JsiObject(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiType(val) {}
JsiObject(panda::Local<panda::ObjectRef> val)302 JsiObject::JsiObject(panda::Local<panda::ObjectRef> val) : JsiType(val) {}
JsiObject(const EcmaVM * vm,panda::Local<panda::ObjectRef> val)303 JsiObject::JsiObject(const EcmaVM *vm, panda::Local<panda::ObjectRef> val) : JsiType(vm, val) {}
304 
IsUndefined() const305 bool JsiObject::IsUndefined() const
306 {
307     if (GetHandle().IsEmpty()) {
308         return true;
309     } else {
310         return GetHandle()->IsUndefined();
311     }
312 }
313 
GetPropertyNames() const314 JsiRef<JsiArray> JsiObject::GetPropertyNames() const
315 {
316     auto vm = GetEcmaVM();
317     return JsiRef<JsiArray>::Make(GetHandle()->GetOwnPropertyNames(vm));
318 }
319 
GetProperty(int32_t propertyIndex) const320 JsiRef<JsiValue> JsiObject::GetProperty(int32_t propertyIndex) const
321 {
322     auto vm = GetEcmaVM();
323     auto str = panda::ExternalStringCache::GetCachedString(vm, propertyIndex);
324     auto value = GetHandle()->Get(vm, str);
325     auto func = JsiValue(vm, value);
326     auto refValue = JsiRef<JsiValue>(func);
327     return refValue;
328 }
329 
HasProperty(int32_t propertyIndex) const330 bool JsiObject::HasProperty(int32_t propertyIndex) const
331 {
332     auto vm = GetEcmaVM();
333     auto stringRef = panda::ExternalStringCache::GetCachedString(vm, propertyIndex);
334     bool has = GetHandle()->Has(vm, stringRef);
335     return has;
336 }
337 
GetProperty(const char * prop) const338 JsiRef<JsiValue> JsiObject::GetProperty(const char* prop) const
339 {
340     auto vm = GetEcmaVM();
341     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
342     auto value = GetHandle()->Get(vm, stringRef);
343     auto func = JsiValue(vm, value);
344     auto refValue =  JsiRef<JsiValue>(func);
345     return refValue;
346 }
347 
HasProperty(const char * prop) const348 bool JsiObject::HasProperty(const char* prop) const
349 {
350     auto vm = GetEcmaVM();
351     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
352     bool has = GetHandle()->Has(vm, stringRef);
353     return has;
354 }
355 
ToJsonObject(const char * value) const356 JsiRef<JsiValue> JsiObject::ToJsonObject(const char* value) const
357 {
358     auto vm = GetEcmaVM();
359     panda::TryCatch trycatch(vm);
360     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(vm, value);
361     panda::Local<JSValueRef> result = JSON::Parse(vm, valueRef);
362     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
363     if (result.IsEmpty() || trycatch.HasCaught()) {
364         runtime->HandleUncaughtException(trycatch);
365         return JsiRef<JsiValue>::Make(JSValueRef::Undefined(vm));
366     }
367 
368     return JsiRef<JsiValue>::Make(result);
369 }
370 
SetPropertyJsonObject(const char * prop,const char * value) const371 void JsiObject::SetPropertyJsonObject(const char* prop, const char* value) const
372 {
373     auto vm = GetEcmaVM();
374     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
375     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(GetEcmaVM(), value);
376     if (valueRef->IsString(vm)) {
377         GetHandle()->Set(vm, stringRef, JSON::Parse(vm, valueRef));
378     }
379 }
380 
SetPropertyObject(const char * prop,JsiRef<JsiValue> value) const381 void JsiObject::SetPropertyObject(const char* prop, JsiRef<JsiValue> value) const
382 {
383     auto vm = GetEcmaVM();
384     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
385     GetHandle()->Set(vm, stringRef, value.Get().GetLocalHandle());
386 }
387 
388 // -----------------------
389 // Implementation of JsiFunction
390 // -----------------------
JsiFunction()391 JsiFunction::JsiFunction() {}
JsiFunction(const panda::CopyableGlobal<panda::FunctionRef> & val)392 JsiFunction::JsiFunction(const panda::CopyableGlobal<panda::FunctionRef>& val) : JsiType(val) {}
393 
JsiFunction(panda::Local<panda::FunctionRef> val)394 JsiFunction::JsiFunction(panda::Local<panda::FunctionRef> val) : JsiType(val) {}
395 
JsiFunction(const EcmaVM * vm,panda::Local<panda::FunctionRef> val)396 JsiFunction::JsiFunction(const EcmaVM *vm, panda::Local<panda::FunctionRef> val) : JsiType(vm, val) {}
397 
Call(JsiRef<JsiValue> thisVal,int argc,JsiRef<JsiValue> argv[]) const398 JsiRef<JsiValue> JsiFunction::Call(JsiRef<JsiValue> thisVal, int argc, JsiRef<JsiValue> argv[]) const
399 {
400     int32_t id = -1;
401     if (SystemProperties::GetAcePerformanceMonitorEnabled()) {
402         id = Container::CurrentId();
403     }
404     JS_CALLBACK_DURATION(id);
405     auto vm = GetEcmaVM();
406     panda::JsiFastNativeScope fastNativeScope(vm);
407     LocalScope scope(vm);
408     panda::TryCatch trycatch(vm);
409     bool traceEnabled = false;
410     if (SystemProperties::GetDebugEnabled()) {
411         traceEnabled = AceTraceBeginWithArgs("ExecuteJS[%s]", GetHandle()->GetName(vm)->ToString(vm).c_str());
412     }
413     std::vector<panda::Local<panda::JSValueRef>> arguments;
414     for (int i = 0; i < argc; ++i) {
415         arguments.emplace_back(argv[i].Get().GetLocalHandle());
416     }
417     auto thisObj = thisVal.Get().GetLocalHandle();
418     auto result = GetHandle()->Call(vm, thisObj, arguments.data(), argc);
419     JSNApi::ExecutePendingJob(vm);
420     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
421     if (result.IsEmpty() || trycatch.HasCaught()) {
422         LOGW("after call jsFunction hasError, empty: %{public}d, caught: %{public}d", result.IsEmpty(),
423             trycatch.HasCaught());
424         runtime->HandleUncaughtException(trycatch);
425         result = JSValueRef::Undefined(vm);
426     }
427     if (traceEnabled) {
428         AceTraceEnd();
429     }
430     return JsiRef<JsiValue>::Make(result);
431 }
432 
New(JsiFunctionCallback func)433 panda::Local<panda::FunctionRef> JsiFunction::New(JsiFunctionCallback func)
434 {
435     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
436     return panda::FunctionRef::New(const_cast<EcmaVM*>(runtime->GetEcmaVm()), func);
437 }
438 
439 // -----------------------
440 // Implementation of JsiObjectTemplate
441 // -----------------------
JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef> & val)442 JsiObjTemplate::JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiObject(val) {}
JsiObjTemplate(panda::Local<panda::ObjectRef> val)443 JsiObjTemplate::JsiObjTemplate(panda::Local<panda::ObjectRef> val) : JsiObject(val) {}
444 
SetInternalFieldCount(int32_t count) const445 void JsiObjTemplate::SetInternalFieldCount(int32_t count) const
446 {
447     GetHandle()->SetNativePointerFieldCount(GetEcmaVM(), count);
448 }
449 
NewInstance() const450 JsiRef<JsiObject> JsiObjTemplate::NewInstance() const
451 {
452     auto instance = panda::ObjectRef::New(GetEcmaVM());
453     instance->SetNativePointerFieldCount(GetEcmaVM(), 1);
454     return JsiRef<JsiObject>::Make(instance);
455 }
456 
New()457 panda::Local<panda::JSValueRef> JsiObjTemplate::New()
458 {
459     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
460     return panda::ObjectRef::New(runtime->GetEcmaVm());
461 }
462 
463 // -----------------------
464 // Implementation of JsiCallBackInfo
465 // -----------------------
JsiCallbackInfo(panda::JsiRuntimeCallInfo * info)466 JsiCallbackInfo::JsiCallbackInfo(panda::JsiRuntimeCallInfo* info) : info_(info) {}
467 
operator [](size_t index) const468 JsiRef<JsiValue> JsiCallbackInfo::operator[](size_t index) const
469 {
470     if (index < Length()) {
471         return JsiRef<JsiValue>::FastMake(info_->GetVM(), info_->GetCallArgRef(index));
472     }
473     return JsiRef<JsiValue>::FastMake(info_->GetVM(), panda::JSValueRef::Undefined(info_->GetVM()));
474 }
475 
This() const476 JsiRef<JsiObject> JsiCallbackInfo::This() const
477 {
478     auto obj = JsiObject { info_->GetVM(), info_->GetThisRef() };
479     auto ref = JsiRef<JsiObject>(obj);
480     return ref;
481 }
482 
Length() const483 uint32_t JsiCallbackInfo::Length() const
484 {
485     return info_->GetArgsNumber();
486 }
487 
ReturnSelf() const488 void JsiCallbackInfo::ReturnSelf() const
489 {
490     panda::CopyableGlobal<panda::JSValueRef> thisObj(info_->GetVM(), info_->GetThisRef());
491     retVal_ = thisObj;
492 }
493 
GetBooleanArg(size_t index,bool & value) const494 bool JsiCallbackInfo::GetBooleanArg(size_t index, bool& value) const
495 {
496     auto arg = info_->GetCallArgRef(index);
497     if (arg.IsEmpty() || !arg->IsBoolean()) {
498         return false;
499     }
500     value = arg->ToBoolean(info_->GetVM())->Value();
501     return true;
502 }
503 
GetInt32Arg(size_t index,int32_t & value) const504 bool JsiCallbackInfo::GetInt32Arg(size_t index, int32_t& value) const
505 {
506     auto arg = info_->GetCallArgRef(index);
507     if (arg.IsEmpty() || !arg->IsNumber()) {
508         return false;
509     }
510     value = arg->Int32Value(info_->GetVM());
511     return true;
512 }
513 
GetUint32Arg(size_t index,uint32_t & value) const514 bool JsiCallbackInfo::GetUint32Arg(size_t index, uint32_t& value) const
515 {
516     auto arg = info_->GetCallArgRef(index);
517     if (arg.IsEmpty() || !arg->IsNumber()) {
518         return false;
519     }
520     value = arg->Uint32Value(info_->GetVM());
521     return true;
522 }
523 
GetDoubleArg(size_t index,double & value,bool isJudgeSpecialValue) const524 bool JsiCallbackInfo::GetDoubleArg(size_t index, double& value, bool isJudgeSpecialValue) const
525 {
526     auto arg = info_->GetCallArgRef(index);
527     if (arg.IsEmpty()) {
528         return false;
529     }
530     bool ret = false;
531     value = arg->GetValueDouble(ret);
532     if (isJudgeSpecialValue) {
533         return (std::isnan(value) || std::isinf(value)) ? false : ret;
534     }
535     return ret;
536 }
537 
GetStringArg(size_t index,std::string & value) const538 bool JsiCallbackInfo::GetStringArg(size_t index, std::string& value) const
539 {
540     auto arg = info_->GetCallArgRef(index);
541     if (arg.IsEmpty() || !arg->IsString(info_->GetVM())) {
542         return false;
543     }
544     value = arg->ToString(info_->GetVM())->ToString(info_->GetVM());
545     return true;
546 }
547 
GetDoubleArrayArg(size_t index,std::vector<double> & valueArr) const548 bool JsiCallbackInfo::GetDoubleArrayArg(size_t index, std::vector<double>& valueArr) const
549 {
550     auto arg = info_->GetCallArgRef(index);
551     if (arg.IsEmpty() || !arg->IsArray(info_->GetVM())) {
552         return false;
553     }
554     auto arrayRef = Local<ArrayRef>(arg);
555     uint32_t length = arrayRef->Length(info_->GetVM());
556     valueArr.reserve(length);
557     for (uint32_t i = 0; i < length; ++i) {
558         auto jsDouble = panda::ArrayRef::GetValueAt(info_->GetVM(), arrayRef, i);
559         if (!jsDouble.IsEmpty() && jsDouble->IsNumber()) {
560             valueArr.emplace_back(jsDouble->ToNumber(info_->GetVM())->Value());
561         }
562     }
563     return true;
564 }
565 
566 // -----------------------
567 // Implementation of JsiString
568 // -----------------------
JsiString(const panda::CopyableGlobal<panda::StringRef> & val)569 JsiString::JsiString(const panda::CopyableGlobal<panda::StringRef>& val) : JsiType(val) {}
JsiString(panda::Local<panda::StringRef> val)570 JsiString::JsiString(panda::Local<panda::StringRef> val) : JsiType(val) {}
571 
New(const char * str)572 panda::Local<panda::StringRef> JsiString::New(const char* str)
573 {
574     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
575     return panda::StringRef::NewFromUtf8(runtime->GetEcmaVm(), str);
576 }
577 
New(const std::string & str)578 panda::Local<panda::StringRef> JsiString::New(const std::string& str)
579 {
580     return JsiString::New(str.c_str());
581 }
582 
583 // -----------------------
584 // Implementation of JsiDate
585 // -----------------------
JsiDate(const panda::CopyableGlobal<panda::DateRef> & val)586 JsiDate::JsiDate(const panda::CopyableGlobal<panda::DateRef>& val) : JsiType(val) {}
JsiDate(panda::Local<panda::DateRef> val)587 JsiDate::JsiDate(panda::Local<panda::DateRef> val) : JsiType(val) {}
588 
New(double value)589 JsiRef<JsiValue> JsiDate::New(double value)
590 {
591     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
592     return JsiRef<JsiValue>::Make(panda::DateRef::New(runtime->GetEcmaVm(), value));
593 }
594 
595 } // namespace OHOS::Ace::Framework
596