• 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 
IsArrayBuffer() const92 bool JsiValue::IsArrayBuffer() const
93 {
94     if (GetHandle().IsEmpty()) {
95         return false;
96     } else {
97         return GetHandle()->IsArrayBuffer();
98     }
99 }
100 
IsUint8ClampedArray() const101 bool JsiValue::IsUint8ClampedArray() const
102 {
103     return (!GetHandle().IsEmpty()) && (GetHandle()->IsUint8ClampedArray());
104 }
105 
IsUndefined() const106 bool JsiValue::IsUndefined() const
107 {
108     if (GetHandle().IsEmpty()) {
109         return true;
110     } else {
111         return GetHandle()->IsUndefined();
112     }
113 }
114 
IsNull() const115 bool JsiValue::IsNull() const
116 {
117     if (GetHandle().IsEmpty()) {
118         return true;
119     } else {
120         return GetHandle()->IsNull();
121     }
122 }
123 
ToString() const124 std::string JsiValue::ToString() const
125 {
126     auto vm = GetEcmaVM();
127     panda::LocalScope scope(vm);
128     if (IsObject()) {
129         return JSON::Stringify(vm, GetLocalHandle())->ToString(vm)->ToString();
130     }
131     return GetHandle()->ToString(vm)->ToString();
132 }
133 
ToBoolean() const134 bool JsiValue::ToBoolean() const
135 {
136     return GetHandle()->BooleaValue();
137 }
138 
Undefined()139 JsiRef<JsiValue> JsiValue::Undefined()
140 {
141     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
142     return JsiRef<JsiValue>::Make(panda::JSValueRef::Undefined(runtime->GetEcmaVm()));
143 }
144 
Null()145 JsiRef<JsiValue> JsiValue::Null()
146 {
147     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
148     return JsiRef<JsiValue>::Make(panda::JSValueRef::Null(runtime->GetEcmaVm()));
149 }
150 
True()151 JsiRef<JsiValue> JsiValue::True()
152 {
153     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
154     return JsiRef<JsiValue>::Make(panda::JSValueRef::True(runtime->GetEcmaVm()));
155 }
156 
False()157 JsiRef<JsiValue> JsiValue::False()
158 {
159     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
160     return JsiRef<JsiValue>::Make(panda::JSValueRef::False(runtime->GetEcmaVm()));
161 }
162 
163 // -----------------------
164 // Implementation of JsiArray
165 // -----------------------
JsiArray()166 JsiArray::JsiArray() {}
JsiArray(const panda::CopyableGlobal<panda::ArrayRef> & val)167 JsiArray::JsiArray(const panda::CopyableGlobal<panda::ArrayRef>& val) : JsiType(val) {}
JsiArray(panda::Local<panda::ArrayRef> val)168 JsiArray::JsiArray(panda::Local<panda::ArrayRef> val) : JsiType(val) {}
169 
GetValueAt(size_t index) const170 JsiRef<JsiValue> JsiArray::GetValueAt(size_t index) const
171 {
172     return JsiRef<JsiValue>::Make(panda::ArrayRef::GetValueAt(GetEcmaVM(), GetLocalHandle(), index));
173 }
174 
SetValueAt(size_t index,JsiRef<JsiValue> value) const175 void JsiArray::SetValueAt(size_t index, JsiRef<JsiValue> value) const
176 {
177     panda::ArrayRef::SetValueAt(GetEcmaVM(), GetLocalHandle(), index, value.Get().GetLocalHandle());
178 }
179 
GetProperty(const char * prop) const180 JsiRef<JsiValue> JsiArray::GetProperty(const char* prop) const
181 {
182     auto vm = GetEcmaVM();
183     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
184     auto value = GetHandle()->Get(vm, stringRef);
185     auto func = JsiValue(value);
186     auto refValue =  JsiRef<JsiValue>(func);
187     return refValue;
188 }
189 
Length() const190 size_t JsiArray::Length() const
191 {
192     size_t length = -1;
193     JsiRef<JsiValue> propLength = GetProperty("length");
194     if (propLength->IsNumber()) {
195         length = propLength->ToNumber<int32_t>();
196     }
197     return length;
198 }
199 
SetLength(size_t length) const200 void JsiArray::SetLength(size_t length) const
201 {
202     auto stringRef = panda::StringRef::NewFromUtf8(GetEcmaVM(), "length");
203     GetHandle()->Set(GetEcmaVM(), stringRef, JsiValueConvertor::toJsiValueWithVM<size_t>(GetEcmaVM(), length));
204 }
205 
IsArray() const206 bool JsiArray::IsArray() const
207 {
208     if (GetHandle().IsEmpty()) {
209         return false;
210     } else {
211         return GetHandle()->IsArray(GetEcmaVM());
212     }
213 }
214 
215 // -----------------------
216 // Implementation of JsiArrayBuffer
217 // -----------------------
JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val)218 JsiArrayBuffer::JsiArrayBuffer(panda::Local<panda::ArrayBufferRef> val) : JsiType(val) {}
JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef> & val)219 JsiArrayBuffer::JsiArrayBuffer(const panda::CopyableGlobal<panda::ArrayBufferRef>& val) : JsiType(val) {}
220 
ByteLength() const221 int32_t JsiArrayBuffer::ByteLength() const
222 {
223     return GetHandle()->ByteLength(GetEcmaVM());
224 }
225 
GetBuffer() const226 void* JsiArrayBuffer::GetBuffer() const
227 {
228     return GetHandle()->GetBuffer();
229 }
230 
Detach() const231 void JsiArrayBuffer::Detach() const
232 {
233     GetHandle()->Detach(GetEcmaVM());
234 }
235 
IsDetach() const236 bool JsiArrayBuffer::IsDetach() const
237 {
238     return GetHandle()->IsDetach();
239 }
240 
241 // -----------------------
242 // Implementation of JsiArrayBufferRef
243 // -----------------------
JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val)244 JsiUint8ClampedArray::JsiUint8ClampedArray(panda::Local<panda::Uint8ClampedArrayRef> val) : JsiType(val) {}
JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef> & val)245 JsiUint8ClampedArray::JsiUint8ClampedArray(const panda::CopyableGlobal<panda::Uint8ClampedArrayRef>& val) : JsiType(val)
246 {}
247 
GetArrayBuffer() const248 JsiRef<JsiArrayBuffer> JsiUint8ClampedArray::GetArrayBuffer() const
249 {
250     return JsiRef<JsiArrayBuffer>(JsiArrayBuffer(GetHandle()->GetArrayBuffer(GetEcmaVM())));
251 }
252 
253 // -----------------------
254 // Implementation of JsiObject
255 // -----------------------
JsiObject()256 JsiObject::JsiObject() : JsiType() {}
JsiObject(const panda::CopyableGlobal<panda::ObjectRef> & val)257 JsiObject::JsiObject(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiType(val) {}
JsiObject(panda::Local<panda::ObjectRef> val)258 JsiObject::JsiObject(panda::Local<panda::ObjectRef> val) : JsiType(val) {}
259 
IsUndefined() const260 bool JsiObject::IsUndefined() const
261 {
262     if (GetHandle().IsEmpty()) {
263         return true;
264     } else {
265         return GetHandle()->IsUndefined();
266     }
267 }
268 
GetPropertyNames() const269 JsiRef<JsiArray> JsiObject::GetPropertyNames() const
270 {
271     auto vm = GetEcmaVM();
272     return JsiRef<JsiArray>::Make(GetHandle()->GetOwnPropertyNames(vm));
273 }
274 
GetProperty(const char * prop) const275 JsiRef<JsiValue> JsiObject::GetProperty(const char* prop) const
276 {
277     auto vm = GetEcmaVM();
278     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
279     auto value = GetHandle()->Get(vm, stringRef);
280     auto func = JsiValue(value);
281     auto refValue =  JsiRef<JsiValue>(func);
282     return refValue;
283 }
284 
HasProperty(const char * prop) const285 bool JsiObject::HasProperty(const char* prop) const
286 {
287     auto vm = GetEcmaVM();
288     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
289     bool has = GetHandle()->Has(vm, stringRef);
290     return has;
291 }
292 
ToJsonObject(const char * value) const293 JsiRef<JsiValue> JsiObject::ToJsonObject(const char* value) const
294 {
295     auto vm = GetEcmaVM();
296     panda::TryCatch trycatch(vm);
297     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(vm, value);
298     panda::Local<JSValueRef> result = JSON::Parse(vm, valueRef);
299     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
300     if (result.IsEmpty() || trycatch.HasCaught()) {
301         runtime->HandleUncaughtException(trycatch);
302         return JsiRef<JsiValue>::Make(JSValueRef::Undefined(vm));
303     }
304 
305     return JsiRef<JsiValue>::Make(result);
306 }
307 
SetPropertyJsonObject(const char * prop,const char * value) const308 void JsiObject::SetPropertyJsonObject(const char* prop, const char* value) const
309 {
310     auto vm = GetEcmaVM();
311     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
312     auto valueRef = JsiValueConvertor::toJsiValueWithVM<std::string>(GetEcmaVM(), value);
313     if (valueRef->IsString()) {
314         GetHandle()->Set(vm, stringRef, JSON::Parse(vm, valueRef));
315     }
316 }
317 
SetPropertyObject(const char * prop,JsiRef<JsiValue> value) const318 void JsiObject::SetPropertyObject(const char* prop, JsiRef<JsiValue> value) const
319 {
320     auto vm = GetEcmaVM();
321     auto stringRef = panda::StringRef::NewFromUtf8(vm, prop);
322     GetHandle()->Set(vm, stringRef, value.Get().GetLocalHandle());
323 }
324 
325 // -----------------------
326 // Implementation of JsiFunction
327 // -----------------------
JsiFunction()328 JsiFunction::JsiFunction() {}
JsiFunction(const panda::CopyableGlobal<panda::FunctionRef> & val)329 JsiFunction::JsiFunction(const panda::CopyableGlobal<panda::FunctionRef>& val) : JsiType(val)
330 {
331 }
332 
JsiFunction(panda::Local<panda::FunctionRef> val)333 JsiFunction::JsiFunction(panda::Local<panda::FunctionRef> val) : JsiType(val)
334 {
335 }
336 
Call(JsiRef<JsiValue> thisVal,int argc,JsiRef<JsiValue> argv[]) const337 JsiRef<JsiValue> JsiFunction::Call(JsiRef<JsiValue> thisVal, int argc, JsiRef<JsiValue> argv[]) const
338 {
339     auto vm = GetEcmaVM();
340     LocalScope scope(vm);
341     panda::TryCatch trycatch(vm);
342     std::vector<panda::Local<panda::JSValueRef>> arguments;
343     for (int i = 0; i < argc; ++i) {
344         arguments.emplace_back(argv[i].Get().GetLocalHandle());
345     }
346     auto thisObj = thisVal.Get().GetLocalHandle();
347     auto result = GetHandle()->Call(vm, thisObj, arguments.data(), argc);
348     JSNApi::ExecutePendingJob(vm);
349     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
350     if (result.IsEmpty() || trycatch.HasCaught()) {
351         runtime->HandleUncaughtException(trycatch);
352         result = JSValueRef::Undefined(vm);
353     }
354     return JsiRef<JsiValue>::Make(result);
355 }
356 
New(JsiFunctionCallback func)357 panda::Local<panda::FunctionRef> JsiFunction::New(JsiFunctionCallback func)
358 {
359     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
360     return panda::FunctionRef::New(const_cast<EcmaVM*>(runtime->GetEcmaVm()), func);
361 }
362 
363 // -----------------------
364 // Implementation of JsiObjectTemplate
365 // -----------------------
JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef> & val)366 JsiObjTemplate::JsiObjTemplate(const panda::CopyableGlobal<panda::ObjectRef>& val) : JsiObject(val) {}
JsiObjTemplate(panda::Local<panda::ObjectRef> val)367 JsiObjTemplate::JsiObjTemplate(panda::Local<panda::ObjectRef> val) : JsiObject(val) {}
368 
SetInternalFieldCount(int32_t count) const369 void JsiObjTemplate::SetInternalFieldCount(int32_t count) const
370 {
371     GetHandle()->SetNativePointerFieldCount(GetEcmaVM(), count);
372 }
373 
NewInstance() const374 JsiRef<JsiObject> JsiObjTemplate::NewInstance() const
375 {
376     auto instance = panda::ObjectRef::New(GetEcmaVM());
377     instance->SetNativePointerFieldCount(GetEcmaVM(), 1);
378     return JsiRef<JsiObject>::Make(instance);
379 }
380 
New()381 panda::Local<panda::JSValueRef> JsiObjTemplate::New()
382 {
383     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
384     return panda::ObjectRef::New(runtime->GetEcmaVm());
385 }
386 
387 // -----------------------
388 // Implementation of JsiCallBackInfo
389 // -----------------------
JsiCallbackInfo(panda::JsiRuntimeCallInfo * info)390 JsiCallbackInfo::JsiCallbackInfo(panda::JsiRuntimeCallInfo* info) : info_(info) {}
391 
operator [](size_t index) const392 JsiRef<JsiValue> JsiCallbackInfo::operator[](size_t index) const
393 {
394     if (static_cast<int32_t>(index) < Length()) {
395         return JsiRef<JsiValue>::Make(info_->GetCallArgRef(index));
396     }
397     return JsiRef<JsiValue>::Make(panda::JSValueRef::Undefined(info_->GetVM()));
398 }
399 
This() const400 JsiRef<JsiObject> JsiCallbackInfo::This() const
401 {
402     auto obj = JsiObject { info_->GetThisRef() };
403     auto ref = JsiRef<JsiObject>(obj);
404     return ref;
405 }
406 
Length() const407 int JsiCallbackInfo::Length() const
408 {
409     return info_->GetArgsNumber();
410 }
411 
ReturnSelf() const412 void JsiCallbackInfo::ReturnSelf() const
413 {
414     panda::CopyableGlobal<panda::JSValueRef> thisObj(info_->GetVM(), info_->GetThisRef());
415     retVal_ = thisObj;
416 }
417 
418 // -----------------------
419 // Implementation of JsiString
420 // -----------------------
JsiString(const char * str)421 JsiString::JsiString(const char* str) : JsiValue(StringRef::NewFromUtf8(GetEcmaVM(), str)) {}
JsiString(JsiValue str)422 JsiString::JsiString(JsiValue str) : JsiValue(str) {}
423 
New(const char * str)424 JsiString JsiString::New(const char* str)
425 {
426     return JsiString(str);
427 }
428 
429 // -----------------------
430 // Implementation of JsiDate
431 // -----------------------
JsiDate(const panda::CopyableGlobal<panda::DateRef> & val)432 JsiDate::JsiDate(const panda::CopyableGlobal<panda::DateRef>& val) : JsiType(val) {}
JsiDate(panda::Local<panda::DateRef> val)433 JsiDate::JsiDate(panda::Local<panda::DateRef> val) : JsiType(val) {}
434 
New(double value)435 JsiRef<JsiValue> JsiDate::New(double value)
436 {
437     auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
438     return JsiRef<JsiValue>::Make(panda::DateRef::New(runtime->GetEcmaVm(), value));
439 }
440 
441 } // namespace OHOS::Ace::Framework
442