• 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/declarative_frontend/engine/quickjs/qjs_types.h"
17 
18 #include "frameworks/bridge/declarative_frontend/engine/quickjs/qjs_bindings.h"
19 #include "frameworks/bridge/declarative_frontend/engine/quickjs/qjs_declarative_engine_instance.h"
20 #include "frameworks/bridge/declarative_frontend/engine/quickjs/qjs_ref.h"
21 #include "frameworks/bridge/js_frontend/engine/quickjs/qjs_utils.h"
22 
23 namespace OHOS::Ace::Framework {
24 
PrintRefCount(JSValue val)25 void PrintRefCount(JSValue val)
26 {
27     if (JS_VALUE_HAS_REF_COUNT(val)) {
28         JSRefCountHeader* p = static_cast<JSRefCountHeader*>(JS_VALUE_GET_PTR(val));
29         LOGE("Ref count of value: %d", p->ref_count);
30     } else {
31         LOGE("no ref count");
32     }
33 }
34 
QJSValue()35 QJSValue::QJSValue()
36 {
37     value_ = JS_UNDEFINED;
38 }
39 
QJSValue(JSValue rhs)40 QJSValue::QJSValue(JSValue rhs)
41 {
42     value_ = rhs;
43 }
44 
~QJSValue()45 QJSValue::~QJSValue() {}
46 
QJSValue(const QJSValue & rhs)47 QJSValue::QJSValue(const QJSValue& rhs)
48 {
49     value_ = rhs.value_;
50 }
51 
QJSValue(QJSValue && rhs)52 QJSValue::QJSValue(QJSValue&& rhs)
53 {
54     value_ = std::move(rhs.value_);
55     rhs.value_ = JS_UNDEFINED;
56 }
57 
operator =(const QJSValue & rhs)58 QJSValue& QJSValue::operator=(const QJSValue& rhs)
59 {
60     value_ = rhs.value_;
61     return *this;
62 }
63 
operator =(QJSValue && rhs)64 QJSValue& QJSValue::operator=(QJSValue&& rhs)
65 {
66     value_ = std::move(rhs.value_);
67     rhs.value_ = JS_UNDEFINED;
68     return *this;
69 }
70 
Dup() const71 QJSValue QJSValue::Dup() const
72 {
73     return QJSValue(JS_DupValue(nullptr, value_));
74 }
75 
Free()76 void QJSValue::Free()
77 {
78     JSRuntime* rt = QJSDeclarativeEngineInstance::GetQJSRuntime();
79     if (rt == nullptr) {
80         LOGE("rt is nullptr");
81         return;
82     }
83     JS_FreeValueRT(rt, value_);
84     value_ = JS_UNDEFINED;
85 }
86 
Reset()87 void QJSValue::Reset()
88 {
89     value_ = JS_UNDEFINED;
90 }
91 
IsEmpty() const92 bool QJSValue::IsEmpty() const
93 {
94     return JS_IsUndefined(value_) || JS_IsNull(value_);
95 }
96 
IsFunction() const97 bool QJSValue::IsFunction() const
98 {
99     return JS_IsFunction(QJSContext::Current(), value_);
100 }
101 
IsNumber() const102 bool QJSValue::IsNumber() const
103 {
104     return JS_IsNumber(value_);
105 }
106 
IsString() const107 bool QJSValue::IsString() const
108 {
109     return JS_IsString(value_);
110 }
111 
IsBoolean() const112 bool QJSValue::IsBoolean() const
113 {
114     return JS_IsBool(value_);
115 }
116 
IsObject() const117 bool QJSValue::IsObject() const
118 {
119     return JS_IsObject(value_);
120 }
121 
IsArray() const122 bool QJSValue::IsArray() const
123 {
124     return JS_IsArray(QJSContext::Current(), value_);
125 }
126 
IsUndefined() const127 bool QJSValue::IsUndefined() const
128 {
129     return JS_IsUndefined(value_);
130 }
131 
IsNull() const132 bool QJSValue::IsNull() const
133 {
134     return JS_IsNull(value_);
135 }
136 
ToString() const137 std::string QJSValue::ToString() const
138 {
139     if (!IsObject()) {
140         return ScopedString(value_);
141     }
142     return ScopedString::Stringify(value_);
143 }
144 
ToBoolean() const145 bool QJSValue::ToBoolean() const
146 {
147     bool value = JS_ToBool(QJSContext::Current(), value_) == 1 ? true : false;
148     return value;
149 }
150 
GetJsContext() const151 JSContext* QJSValue::GetJsContext() const
152 {
153     return QJSContext::Current();
154 }
155 
QJSObject()156 QJSObject::QJSObject() : QJSValue() {}
QJSObject(JSValue val)157 QJSObject::QJSObject(JSValue val) : QJSValue(val) {}
158 
New()159 QJSObject QJSObject::New()
160 {
161     return QJSObject(JS_NewObject(QJSContext::Current()));
162 }
163 
GetPropertyNames() const164 QJSRef<QJSArray> QJSObject::GetPropertyNames() const
165 {
166     JSPropertyEnum* pTab = nullptr;
167     uint32_t len = 0;
168     if (!CheckAndGetJsProperty(QJSContext::Current(), GetHandle(), &pTab, &len)) {
169         return QJSRef<QJSArray>::Make(QJSArray::New());
170     }
171     JS_GetOwnPropertyNames(QJSContext::Current(), &pTab, &len, GetHandle(), JS_GPN_STRING_MASK);
172     JSValue value = JS_AtomToValue(QJSContext::Current(), pTab->atom);
173     return QJSRef<QJSArray>::Make(value);
174 }
175 
GetProperty(const char * prop) const176 QJSRef<QJSValue> QJSObject::GetProperty(const char* prop) const
177 {
178     return QJSRef<QJSValue>::Make(JS_GetPropertyStr(QJSContext::Current(), GetHandle(), prop));
179 }
180 
ToJsonObject(const char * value) const181 QJSRef<QJSValue> QJSObject::ToJsonObject(const char* value) const
182 {
183     JSContext* ctx = QJSContext::Current();
184     JSValue jsonObj = JS_ParseJSON(ctx, value, strlen(value), "");
185     return QJSRef<QJSValue>::Make(jsonObj);
186 }
187 
SetPropertyJsonObject(const char * prop,const char * value) const188 void QJSObject::SetPropertyJsonObject(const char* prop, const char* value) const
189 {
190     JSContext* ctx = QJSContext::Current();
191     JSValue jsonObj = JS_ParseJSON(ctx, value, strlen(value), "");
192     JS_SetPropertyStr(ctx, GetHandle(), prop, jsonObj);
193 }
194 
SetPropertyObject(const char * prop,QJSRef<QJSValue> value) const195 void QJSObject::SetPropertyObject(const char* prop, QJSRef<QJSValue> value) const
196 {
197     JS_SetPropertyStr(QJSContext::Current(), GetHandle(), prop, value->GetHandle());
198 }
199 
New()200 JSValue QJSObjTemplate::New()
201 {
202     return JS_NewObject(QJSContext::Current());
203 }
204 
QJSObjTemplate(JSValue val)205 QJSObjTemplate::QJSObjTemplate(JSValue val) : QJSValue(val) {}
206 
SetInternalFieldCount(int32_t count) const207 void QJSObjTemplate::SetInternalFieldCount(int32_t count) const {}
208 
NewInstance() const209 QJSRef<QJSObject> QJSObjTemplate::NewInstance() const
210 {
211     return QJSRef<QJSObject>::Make(JS_NewObject(QJSContext::Current()));
212 }
213 
QJSFunction()214 QJSFunction::QJSFunction() {}
QJSFunction(JSValue val)215 QJSFunction::QJSFunction(JSValue val) : QJSValue(val), ctx_(QJSContext::Current()) {}
216 
Call(QJSRef<QJSValue> thisVal,int argc,QJSRef<QJSValue> argv[]) const217 QJSRef<QJSValue> QJSFunction::Call(QJSRef<QJSValue> thisVal, int argc, QJSRef<QJSValue> argv[]) const
218 {
219     std::vector<JSValue> args;
220     for (int i = 0; i < argc; ++i) {
221         args.push_back(argv[i].Get().GetHandle());
222     }
223     QJSContext::Scope scp(ctx_);
224     JSValue res = JS_Call(QJSContext::Current(), GetHandle(), thisVal.Get().GetHandle(), argc, args.data());
225     if (JS_IsException(res)) {
226         QJSUtils::JsStdDumpErrorAce(QJSContext::Current());
227         JS_FreeValue(QJSContext::Current(), res);
228         return QJSRef<QJSValue>::Make(JS_NULL);
229     }
230     js_std_loop(ctx_);
231     return QJSRef<QJSValue>::Make(res);
232 }
233 
New(FunctionCallback func)234 JSValue QJSFunction::New(FunctionCallback func)
235 {
236     JSValue funcObj = JS_NewCFunction2(QJSContext::Current(), func, "callback", 0, JS_CFUNC_constructor_or_func, 0);
237     return funcObj;
238 }
239 
QJSArray()240 QJSArray::QJSArray() {}
QJSArray(JSValue val)241 QJSArray::QJSArray(JSValue val) : QJSValue(val) {}
242 
New()243 QJSArray QJSArray::New()
244 {
245     return QJSArray(JS_NewArray(QJSContext::Current()));
246 }
247 
GetValueAt(size_t index) const248 QJSRef<QJSValue> QJSArray::GetValueAt(size_t index) const
249 {
250     JSContext* ctx = QJSContext::Current();
251     JSValue val = JS_GetPropertyUint32(ctx, GetHandle(), index);
252     return QJSRef<QJSValue>::Make(val);
253 }
254 
SetValueAt(size_t index,QJSRef<QJSValue> value) const255 void QJSArray::SetValueAt(size_t index, QJSRef<QJSValue> value) const
256 {
257     JSContext* ctx = QJSContext::Current();
258     JS_SetPropertyUint32(ctx, GetHandle(), index, value.Get().GetHandle());
259 }
260 
Length() const261 size_t QJSArray::Length() const
262 {
263     return QJSUtils::JsGetArrayLength(QJSContext::Current(), GetHandle());
264 }
265 
QJSString(const char * str)266 QJSString::QJSString(const char* str) : QJSValue(JS_NewStringLen(QJSContext::Current(), str, strlen(str))) {}
QJSString(JSValue str)267 QJSString::QJSString(JSValue str) : QJSValue(str) {}
268 
New(const char * str)269 QJSString QJSString::New(const char* str)
270 {
271     return QJSString(str);
272 }
QJSCallbackInfo(JSContext * ctx,JSValueConst thisObj,int argc,JSValueConst * argv)273 QJSCallbackInfo::QJSCallbackInfo(JSContext* ctx, JSValueConst thisObj, int argc, JSValueConst* argv)
274     : ctx_(ctx), thisObj_(thisObj), argc_(argc), argv_(argv)
275 {}
276 
operator [](size_t index) const277 QJSRef<QJSValue> QJSCallbackInfo::operator[](size_t index) const
278 {
279     QJSRef<QJSValue> val = QJSRef<QJSValue>::Make(argv_[index]);
280     return val;
281 }
282 
This() const283 QJSRef<QJSObject> QJSCallbackInfo::This() const
284 {
285     return QJSRef<QJSObject>::Make(thisObj_);
286 }
287 
Length() const288 int QJSCallbackInfo::Length() const
289 {
290     return argc_;
291 }
292 
ReturnSelf() const293 void QJSCallbackInfo::ReturnSelf() const
294 {
295     retVal_ = JS_DupValue(nullptr, thisObj_);
296 }
297 
QJSGCMarkCallbackInfo(JSRuntime * rt,JS_MarkFunc * markFunc)298 QJSGCMarkCallbackInfo::QJSGCMarkCallbackInfo(JSRuntime* rt, JS_MarkFunc* markFunc) : rt_(rt), markFunc_(markFunc) {}
299 
Mark(JSValue val) const300 void QJSGCMarkCallbackInfo::Mark(JSValue val) const
301 {
302     JS_MarkValue(rt_, val, markFunc_);
303 }
304 
305 } // namespace OHOS::Ace::Framework
306