• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <cstddef>
17 #include <ctime>
18 #include <sys/time.h>
19 
20 #include "gtest/gtest.h"
21 
22 #include "assembler/assembly-parser.h"
23 #include "ecmascript/builtins/builtins.h"
24 #include "ecmascript/builtins/builtins_function.h"
25 #include "ecmascript/builtins/builtins_locale.h"
26 #include "ecmascript/compiler/aot_file/an_file_data_manager.h"
27 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
28 #include "ecmascript/ecma_global_storage.h"
29 #include "ecmascript/ecma_vm.h"
30 #include "ecmascript/global_env.h"
31 #include "ecmascript/js_api/js_api_deque.h"
32 #include "ecmascript/js_api/js_api_queue.h"
33 #include "ecmascript/js_bigint.h"
34 #include "ecmascript/js_generator_object.h"
35 #include "ecmascript/js_list_format.h"
36 #include "ecmascript/js_runtime_options.h"
37 #include "ecmascript/js_thread.h"
38 #include "ecmascript/jspandafile/js_pandafile_manager.h"
39 #include "ecmascript/napi/include/jsnapi.h"
40 #include "ecmascript/napi/jsnapi_helper.h"
41 #include "ecmascript/object_factory.h"
42 #include "ecmascript/tagged_array.h"
43 #include "ecmascript/tests/test_helper.h"
44 
45 using namespace panda;
46 using namespace panda::ecmascript;
47 using namespace panda::pandasm;
48 using namespace panda::panda_file;
49 
50 namespace panda::test {
51 class JSNApiSampleTest : public testing::Test {
52 public:
SetUp()53     void SetUp() override
54     {
55         RuntimeOption option;
56         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
57         vm_ = JSNApi::CreateJSVM(option);
58         thread_ = vm_->GetJSThread();
59         vm_->SetEnableForceGC(true);
60     }
61 
TearDown()62     void TearDown() override
63     {
64         vm_->SetEnableForceGC(false);
65         JSNApi::DestroyJSVM(vm_);
66     }
67 
68 protected:
69     JSThread *thread_ = nullptr;
70     EcmaVM *vm_ = nullptr;
71 };
72 
73 /* demo1 原始类型的使用。 */
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_IntegerRef)74 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_IntegerRef)
75 {
76     LocalScope scope(vm_);
77     GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_int=============================================================";
78     int inputInt = 123; // int value = 123
79     Local<IntegerRef> intObject = IntegerRef::New(vm_, inputInt);
80     int intValue = intObject->Value();
81     GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_intValue : " << intValue;
82     Local<PrimitiveRef> pintObject = intObject;
83     GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_pintObject_IsInt : " << pintObject->IsInt();
84     GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_uint============================================================";
85     uint inputUint = 123; // uint value = 123
86     Local<IntegerRef> uintObject = IntegerRef::NewFromUnsigned(vm_, inputUint);
87     int uintValue = uintObject->Value();
88     GTEST_LOG_(INFO) << "sample_primitive_uintValue : " << uintValue;
89 }
90 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_NumberRef)91 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_NumberRef)
92 {
93     LocalScope scope(vm_);
94     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_double===========================================================";
95     double inputDouble = 3.14; // double value = 3.14
96     Local<NumberRef> doubleObject = NumberRef::New(vm_, inputDouble);
97     double doubleValue = doubleObject->Value();
98     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_doubleValue : " << doubleValue;
99     Local<PrimitiveRef> pdoubleObject = doubleObject;
100     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_pdoubleObject_IsNumber : " << pdoubleObject->IsNumber();
101     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int32_t==========================================================";
102     int32_t inputInt32t = 666; // int32-t value = 666
103     Local<NumberRef> int32tObject = NumberRef::New(vm_, inputInt32t);
104     double int32tValue = int32tObject->Value();
105     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int32tValue : " << int32tValue;
106     Local<PrimitiveRef> pint32tObject = int32tObject;
107     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_pint32tObject_Int32Value : " << pint32tObject->Int32Value(vm_);
108     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_uint32_t=========================================================";
109     uint32_t inputUint32t = 666; // uint32_t value = 666
110     Local<NumberRef> uint32tObject = NumberRef::New(vm_, inputUint32t);
111     double uint32tValue = uint32tObject->Value();
112     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_uint32tValue : " << uint32tValue;
113     Local<PrimitiveRef> puint32tObject = uint32tObject;
114     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_puint32tObject_Uint32Value : " << puint32tObject->Uint32Value(vm_);
115     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int64_t==========================================================";
116     int64_t inputInt64t = 666; // int64_t value = 666
117     Local<NumberRef> int64tObject = NumberRef::New(vm_, inputInt64t);
118     double int64tValue = int64tObject->Value();
119     GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int64tValue : " << int64tValue;
120 }
121 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_BigIntRef_Uint64)122 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_BigIntRef_Uint64)
123 {
124     LocalScope scope(vm_);
125     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_uint64_t=========================================================";
126     uint64_t inputUint64t = 999; // uint64_t value = 999
127     Local<BigIntRef> uint64tObject = BigIntRef::New(vm_, inputUint64t);
128     int64_t ucValue = 0;
129     bool uLossless = true;
130     uint64_t ucValue1 = 0;
131     uint64tObject->BigIntToInt64(vm_, &ucValue, &uLossless);
132     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToInt64 : " << ucValue;
133     uint64tObject->BigIntToUint64(vm_, &ucValue1, &uLossless);
134     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToUint64 : " << ucValue1;
135     bool uSign = false;
136     uint32_t uSize = 3;
137     int uarraySize = 3;
138     const uint64_t uWords[3] = {666, 777, 888};
139     Local<JSValueRef> ubigWords = BigIntRef::CreateBigWords(vm_, uSign, uSize, uWords);
140     for (int i = 0; i < uarraySize; i++) {
141         GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_UwordsArrayindex"
142                          << " [ " << i << " ] : " << uWords[i];
143     }
144     Local<BigIntRef> ubigWordsRef(ubigWords);
145     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_UArraySize : " << ubigWordsRef->GetWordsArraySize(vm_);
146     bool uresultSignBit = true;
147     int unewarraySize = 3;
148     uint64_t *uresultWords = new uint64_t[unewarraySize]();
149     ubigWordsRef->GetWordsArray(vm_, &uresultSignBit, uSize, uresultWords);
150     for (int i = 0; i < unewarraySize; i++) {
151         GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_uresultWords"
152                          << " [ " << i << " ] : " << uresultWords[i];
153     }
154 }
155 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_BigIntRef_Int64)156 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_BigIntRef_Int64)
157 {
158     LocalScope scope(vm_);
159     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_int64_t==========================================================";
160     int64_t inputInt64t = 111; // int64_t value = 111
161     Local<BigIntRef> int64tObject = BigIntRef::New(vm_, inputInt64t);
162     int64_t icValue = 0;
163     bool iLossless = true;
164     uint64_t icValue1 = 0;
165     int64tObject->BigIntToInt64(vm_, &icValue, &iLossless);
166     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToInt64 : " << icValue;
167     int64tObject->BigIntToUint64(vm_, &icValue1, &iLossless);
168     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToUint64 : " << icValue1;
169     bool iSign = false;
170     uint32_t iSize = 3;
171     int iarraySize = 3;
172     const uint64_t iWords[3] = {222, 333, 444};
173     Local<JSValueRef> ibigWords = BigIntRef::CreateBigWords(vm_, iSign, iSize, iWords);
174     for (int i = 0; i < iarraySize; i++) {
175         GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_iWordsArrayindex"
176                          << " [ " << i << " ] : " << iWords[i];
177     }
178     Local<BigIntRef> ibigWordsRef(ibigWords);
179     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_iarraySize : " << ibigWordsRef->GetWordsArraySize(vm_);
180     bool iresultSignBit = true;
181     int inewarraySize = 3;
182     uint64_t *iresultWords = new uint64_t[inewarraySize]();
183     ibigWordsRef->GetWordsArray(vm_, &iresultSignBit, iSize, iresultWords);
184     for (int i = 0; i < inewarraySize; i++) {
185         GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_iresultWords"
186                          << " [ " << i << " ] : " << iresultWords[i];
187     }
188     Local<PrimitiveRef> pint64tObject = int64tObject;
189     GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_pint64tObject_IsBigInt : " << pint64tObject->IsBigInt(vm_);
190 }
191 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_BooleanRef)192 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_BooleanRef)
193 {
194     LocalScope scope(vm_);
195     GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_true============================================================";
196     Local<BooleanRef> trueObject = BooleanRef::New(vm_, true);
197     GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_trueObject_Value : " << trueObject->Value();
198     Local<PrimitiveRef> ptrueObject = trueObject;
199     GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_ptrueObject_IsBoolean : " << ptrueObject->IsBoolean();
200     GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_false===========================================================";
201     Local<BooleanRef> falseObject = BooleanRef::New(vm_, false);
202     GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_falseObject_Value : " << falseObject->Value();
203     Local<PrimitiveRef> pfalseObject = falseObject;
204     GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_pfalseObject_IsBoolean : " << pfalseObject->IsBoolean();
205 }
206 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_StringRef_Char)207 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_StringRef_Char)
208 {
209     LocalScope scope(vm_);
210     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char=============================================================";
211     char utf8[12] = "Hello world";
212     Local<JSValueRef> local = StringRef::NewFromUtf8(vm_, utf8);
213     JSValueRef *jsValue = (*local);
214     StringRef *charObject = StringRef::Cast(jsValue);
215     EXPECT_EQ(charObject->Utf8Length(vm_), 12);
216     char buffer[12];
217     EXPECT_EQ(charObject->WriteUtf8(vm_, buffer, 12), 12);
218     std::string res(buffer);
219     GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject : " << res;
220     std::string charObjectStr = charObject->ToString(vm_);
221     GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_ToString : " << charObjectStr;
222     uint32_t charSize = charObject->Length(vm_);
223     GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_Length : " << charSize;
224     char cs[16] = {0};
225     uint32_t length = charObject->WriteLatin1(vm_, cs, 12);
226     GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_WriteLatin1 : " << length;
227     Local<StringRef> napiWrapperString = charObject->GetNapiWrapperString(vm_);
228     EXPECT_EQ(napiWrapperString->Utf8Length(vm_), 13);
229     char buffer1[12];
230     EXPECT_EQ(charObject->WriteUtf8(vm_, buffer1, 12), 12);
231     std::string res1(buffer1);
232     GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_GetNapiWrapperString : " << res1;
233     PrimitiveRef *pcharObject = charObject;
234     GTEST_LOG_(INFO) << "sample_primitive_StringRef_pcharObject_IsString : " << pcharObject->IsString(vm_);
235 }
236 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_StringRef_Char16)237 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_StringRef_Char16)
238 {
239     LocalScope scope(vm_);
240     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16_t=========================================================";
241     const char16_t *utf16 = u"Hi,ABCDEF";
242     Local<JSValueRef> local = StringRef::NewFromUtf16(vm_, utf16);
243     JSValueRef *jsValue = (*local);
244     StringRef *char16tObject = StringRef::Cast(jsValue);
245     EXPECT_EQ(char16tObject->Utf8Length(vm_), 10);
246     char16_t buffer2[10];
247     EXPECT_EQ(char16tObject->WriteUtf16(vm_, buffer2, 9), 9);
248     std::string res2(buffer2, buffer2 + sizeof(buffer2) / sizeof(char16_t));
249     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject : " << res2 << std::endl;
250     std::string char16tObjectStr = char16tObject->ToString(vm_);
251     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject_ToString : " << char16tObjectStr;
252     uint32_t charSize = char16tObject->Length(vm_);
253     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject_Length : " << charSize;
254     char cs1[10] = {0};
255     uint32_t length = char16tObject->WriteLatin1(vm_, cs1, 10);
256     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject_WriteLatin1 : " << length;
257     Local<StringRef> napiWrapperString = char16tObject->GetNapiWrapperString(vm_);
258     EXPECT_EQ(napiWrapperString->Utf8Length(vm_), 13);
259     char16_t buffer3[10];
260     EXPECT_EQ(char16tObject->WriteUtf16(vm_, buffer3, 9), 9);
261     std::string res3(buffer3, buffer3 + sizeof(buffer3) / sizeof(char16_t));
262     GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject : " << res3;
263     PrimitiveRef *pchar16tObject = char16tObject;
264     GTEST_LOG_(INFO) << "sample_primitive_StringRef_pchar16tObject_IsString : " << pchar16tObject->IsString(vm_);
265 }
266 
HWTEST_F_L0(JSNApiSampleTest,Sample_PrimitiveRef_SymbolRef)267 HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_SymbolRef)
268 {
269     LocalScope scope(vm_);
270     GTEST_LOG_(INFO) << "sample_primitive_SymbolRef==================================================================";
271     Local<SymbolRef> symbolObject = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "description"));
272     Local<StringRef> symbolDescription = symbolObject->GetDescription(vm_);
273     GTEST_LOG_(INFO) << "sample_primitive_symbol_description : " << symbolDescription->ToString(vm_);
274     Local<PrimitiveRef> psymbolObject = symbolObject;
275     GTEST_LOG_(INFO) << "sample_primitive_SymbolRef_Psym_IsSymbol : " << psymbolObject->IsSymbol(vm_);
276 }
277 
278 /* demo2 本地指针包装的使用。 */
279 class NativePointerTestClass {
280 public:
NativePointerTestClass()281     NativePointerTestClass() : someProperty(0)
282     {
283         GTEST_LOG_(INFO) << "NativePointerTestClass Construction";
284     }
285 
~NativePointerTestClass()286     ~NativePointerTestClass()
287     {
288         GTEST_LOG_(INFO) << "NativePointerTestClass Destruction";
289     }
290 
GetsomeProperty() const291     int GetsomeProperty() const
292     {
293         return someProperty;
294     }
295 
SetsomeProperty(int value)296     void SetsomeProperty(int value)
297     {
298         someProperty = value;
299     }
300 
301 private:
302     int someProperty;
303 };
304 
HWTEST_F_L0(JSNApiSampleTest,sample_NativePointerRef)305 HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef)
306 {
307     LocalScope scope(vm_);
308     NativePointerTestClass *nativePointerTestClass = new NativePointerTestClass();
309     GTEST_LOG_(INFO) << "sample_NativePointer adress: " << nativePointerTestClass;
310     Local<NativePointerRef> nativePoint = NativePointerRef::New(
311         vm_, nativePointerTestClass,
312         [](void *env, void *value, void *hint) {
313             GTEST_LOG_(INFO) << "NativePointerCb value : " << value;
314             GTEST_LOG_(INFO) << "NativePointerCb hint  : " << hint;
315             NativePointerTestClass *ptr = static_cast<NativePointerTestClass *>(value);
316             delete ptr;
317         },
318         (void *)0x123);
319     NativePointerTestClass *yourClassPtr = static_cast<NativePointerTestClass *>(nativePoint->Value());
320     GTEST_LOG_(INFO) << "sample_NativePointer GetValue : " << yourClassPtr->GetsomeProperty();
321     yourClassPtr->SetsomeProperty(99);
322     GTEST_LOG_(INFO) << "sample_NativePointer SetValue : " << yourClassPtr->GetsomeProperty();
323     GTEST_LOG_(INFO) << "sample_NativePointer Value : " << nativePoint->Value();
324 }
325 
HWTEST_F_L0(JSNApiSampleTest,sample_NativePointerRef_String)326 HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_String)
327 {
328     LocalScope scope(vm_);
329     void *vps = new std::string("123456");
330     Local<NativePointerRef> nativePoint = NativePointerRef::New(vm_, vps);
331     std::string *p = (std::string *)nativePoint->Value();
332     GTEST_LOG_(INFO) << "sample_NativePointerRef_String Value : " << *p;
333     std::string value = "78910";
334     *p = value;
335     GTEST_LOG_(INFO) << "sample_NativePointerRef_String ChangeValue : " << *((std::string *)nativePoint->Value());
336 }
337 
HWTEST_F_L0(JSNApiSampleTest,sample_NativePointerRef_Double)338 HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Double)
339 {
340     LocalScope scope(vm_);
341     void *vpd = new double(123.456);
342     Local<NativePointerRef> nativePoint = NativePointerRef::New(vm_, vpd);
343     double *p = (double *)nativePoint->Value();
344     GTEST_LOG_(INFO) << "sample_NativePointerRef_Double Value : " << *p;
345     double value = 66.66;
346     *p = value;
347     GTEST_LOG_(INFO) << "sample_NativePointerRef_Double ChangeValue: " << *((double *)nativePoint->Value());
348 }
349 
HWTEST_F_L0(JSNApiSampleTest,sample_NativePointerRef_Char)350 HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Char)
351 {
352     LocalScope scope(vm_);
353     void *vpc = new char('a');
354     Local<NativePointerRef> nativePoint = NativePointerRef::New(vm_, vpc);
355     char *p = (char *)nativePoint->Value();
356     GTEST_LOG_(INFO) << "sample_NativePointerRef_Char Value : " << *p;
357     *p = 'A';
358     GTEST_LOG_(INFO) << "sample_NativePointerRef_Char ChangeValue: " << *((char *)nativePoint->Value());
359 }
360 
HWTEST_F_L0(JSNApiSampleTest,sample_NativePointerRef_Long)361 HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Long)
362 {
363     LocalScope scope(vm_);
364     void *vpl = new long(123456);
365     Local<NativePointerRef> nativePoint = NativePointerRef::New(vm_, vpl);
366     long *p = (long *)nativePoint->Value();
367     GTEST_LOG_(INFO) << "sample_NativePointerRef_Long Value : " << *p;
368     long value = 2147483647;
369     *p = value;
370     GTEST_LOG_(INFO) << "sample_NativePointerRef_Long ChangeValue: " << *((long *)nativePoint->Value());
371 }
372 
HWTEST_F_L0(JSNApiSampleTest,sample_NativePointerRef_Int)373 HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Int)
374 {
375     LocalScope scope(vm_);
376     void *vpi = new int(123);
377     Local<NativePointerRef> nativePoint = NativePointerRef::New(vm_, vpi);
378     int *p = (int *)nativePoint->Value();
379     GTEST_LOG_(INFO) << "sample_NativePointerRef_Int Value : " << *p;
380     int value = 147483647;
381     *p = value;
382     GTEST_LOG_(INFO) << "sample_NativePointerRef_Int ChangeValue: " << *((int *)nativePoint->Value());
383 }
384 
385 /* demo3 对object的操作 */
GetSymbolRef(EcmaVM * vm)386 static std::vector<Local<SymbolRef>> GetSymbolRef(EcmaVM *vm)
387 {
388     GTEST_LOG_(INFO) << "GetSymbolRef";
389     static std::vector<Local<SymbolRef>> value = { SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "symbolKey1")),
390                                                    SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "symbolKey2")),
391                                                    SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "symbolKey3")) };
392     return value;
393 }
394 
Setter1(JsiRuntimeCallInfo * info)395 Local<JSValueRef> Setter1(JsiRuntimeCallInfo *info)
396 {
397     GTEST_LOG_(INFO) << "Setter is running";
398     int cnt = 0; // 0 = first element
399     EscapeLocalScope scope(info->GetVM());
400     Local<JSValueRef> arg = info->GetCallArgRef(0);
401     Local<JSValueRef> value = info->GetThisRef();
402     Local<ObjectRef> obj = value->ToObject(info->GetVM());
403     if (value->IsNumber()) {
404         double num = value->ToNumber(info->GetVM())->Value();
405         int max = 100; // 100 = maxValue
406         int min = 0;   // 0 = minValue
407         if (num < min || num > max) {
408             return JSValueRef::Undefined(info->GetVM());
409         }
410     }
411     obj->Set(info->GetVM(), GetSymbolRef(info->GetVM())[cnt], arg);
412     return JSValueRef::Undefined(info->GetVM());
413 }
414 
Setter2(JsiRuntimeCallInfo * info)415 Local<JSValueRef> Setter2(JsiRuntimeCallInfo *info)
416 {
417     GTEST_LOG_(INFO) << "Setter is running";
418     int cnt = 1; // 1 = second element
419     EscapeLocalScope scope(info->GetVM());
420     Local<JSValueRef> arg = info->GetCallArgRef(0);
421     Local<JSValueRef> value = info->GetThisRef();
422     Local<ObjectRef> obj = value->ToObject(info->GetVM());
423     if (!arg->IsString(info->GetVM())) {
424         return JSValueRef::Undefined(info->GetVM());
425     }
426     obj->Set(info->GetVM(), GetSymbolRef(info->GetVM())[cnt], arg);
427     return JSValueRef::Undefined(info->GetVM());
428 }
429 
Setter3(JsiRuntimeCallInfo * info)430 Local<JSValueRef> Setter3(JsiRuntimeCallInfo *info)
431 {
432     GTEST_LOG_(INFO) << "Setter is running";
433     int cnt = 2; // 2 = third element
434     EscapeLocalScope scope(info->GetVM());
435     Local<JSValueRef> arg = info->GetCallArgRef(0);
436     Local<JSValueRef> value = info->GetThisRef();
437     Local<ObjectRef> obj = value->ToObject(info->GetVM());
438     if (!arg->IsSymbol(info->GetVM())) {
439         return JSValueRef::Undefined(info->GetVM());
440     }
441     obj->Set(info->GetVM(), GetSymbolRef(info->GetVM())[cnt], arg);
442     return JSValueRef::Undefined(info->GetVM());
443 }
444 
Getter1(JsiRuntimeCallInfo * info)445 Local<JSValueRef> Getter1(JsiRuntimeCallInfo *info)
446 {
447     GTEST_LOG_(INFO) << "Getter is running";
448     int cnt = 0; // 0 = first element
449     Local<JSValueRef> value = info->GetThisRef();
450     Local<ObjectRef> obj = value->ToObject(info->GetVM());
451     Local<JSValueRef> temp = obj->Get(info->GetVM(), GetSymbolRef(info->GetVM())[cnt]);
452     return temp->ToString(info->GetVM());
453 }
454 
Getter2(JsiRuntimeCallInfo * info)455 Local<JSValueRef> Getter2(JsiRuntimeCallInfo *info)
456 {
457     GTEST_LOG_(INFO) << "Getter is running";
458     int cnt = 1; // 1 = second element
459     Local<JSValueRef> value = info->GetThisRef();
460     Local<ObjectRef> obj = value->ToObject(info->GetVM());
461     Local<JSValueRef> temp = obj->Get(info->GetVM(), GetSymbolRef(info->GetVM())[cnt]);
462     return temp->ToString(info->GetVM());
463 }
464 
Getter3(JsiRuntimeCallInfo * info)465 Local<JSValueRef> Getter3(JsiRuntimeCallInfo *info)
466 {
467     GTEST_LOG_(INFO) << "Getter is running";
468     int cnt = 2; // 2 = third element
469     Local<JSValueRef> value = info->GetThisRef();
470     Local<ObjectRef> obj = value->ToObject(info->GetVM());
471     Local<JSValueRef> temp = obj->Get(info->GetVM(), GetSymbolRef(info->GetVM())[cnt]);
472     if (!temp->IsSymbol(info->GetVM())) {
473         JSValueRef::Undefined(info->GetVM());
474     }
475     Local<SymbolRef> str = temp;
476     return str->GetDescription(info->GetVM());
477 }
478 
ObjectRefSet(Local<ObjectRef> object,EcmaVM * vm,Local<SymbolRef> symbol)479 void ObjectRefSet(Local<ObjectRef> object, EcmaVM *vm, Local<SymbolRef> symbol)
480 {
481     GTEST_LOG_(INFO) << "ObjectRefSet";
482     int cnt = 1; // 1 = key
483     bool b = object->Set(vm, cnt, StringRef::NewFromUtf8(vm, "TestValue1"));
484     ASSERT_TRUE(b);
485     b = object->Set(vm, StringRef::NewFromUtf8(vm, "Test2"), StringRef::NewFromUtf8(vm, "TestValue2"));
486     ASSERT_TRUE(b);
487     b = object->Set(vm, StringRef::NewFromUtf8(vm, "Test3"), StringRef::NewFromUtf8(vm, "TestValue3"));
488     ASSERT_TRUE(b);
489     b = object->Set(vm, symbol, StringRef::NewFromUtf8(vm, "symbolValue"));
490     ASSERT_TRUE(b);
491 
492     Local<FunctionRef> getter1 = FunctionRef::New(vm, Getter1);
493     Local<FunctionRef> setter1 = FunctionRef::New(vm, Setter1);
494 
495     Local<FunctionRef> getter2 = FunctionRef::New(vm, Getter2);
496     Local<FunctionRef> setter2 = FunctionRef::New(vm, Setter2);
497 
498     Local<FunctionRef> getter3 = FunctionRef::New(vm, Getter3);
499     Local<FunctionRef> setter3 = FunctionRef::New(vm, Setter3);
500 
501     PropertyAttribute attribute1(StringRef::NewFromUtf8(vm, "AttributeValue1"), true, true, false);
502     PropertyAttribute attribute2(StringRef::NewFromUtf8(vm, "AttributeValue2"), false, true, true);
503     PropertyAttribute attribute3(StringRef::NewFromUtf8(vm, "AttributeValue3"), true, false, true);
504     attribute1.SetGetter(getter1);
505     attribute1.SetSetter(setter1);
506     b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"), attribute1);
507     ASSERT_TRUE(b);
508     b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "Test2"), attribute2);
509     ASSERT_TRUE(b);
510     b = object->SetAccessorProperty(vm, StringRef::NewFromUtf8(vm, "Accessor1"), getter1, setter1);
511     ASSERT_TRUE(b);
512     b = object->SetAccessorProperty(vm, StringRef::NewFromUtf8(vm, "Test3"), getter2, setter2);
513     ASSERT_TRUE(b);
514     b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"), attribute3);
515     ASSERT_TRUE(b);
516     b = object->SetAccessorProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"), getter3, setter3, attribute3);
517     ASSERT_TRUE(b);
518 }
519 
GetProperty(Local<ObjectRef> object,EcmaVM * vm)520 void GetProperty(Local<ObjectRef> object, EcmaVM *vm)
521 {
522     GTEST_LOG_(INFO) << "GetProperty";
523     Local<ArrayRef> names = object->GetOwnPropertyNames(vm);
524     int cnt = names->Length(vm);
525     GTEST_LOG_(INFO) << "GetOwnPropertyNames cnt: " << cnt;
526     for (int i = 0; i < cnt; i++) {
527         Local<JSValueRef> value = ArrayRef::GetValueAt(vm, names, i);
528         if (value->IsSymbol(vm)) {
529             Local<SymbolRef> symbol = value;
530             GTEST_LOG_(INFO) << "PropertyNames: " << symbol->GetDescription(vm)->ToString(vm);
531         } else {
532             GTEST_LOG_(INFO) << "PropertyNames: " << value->ToString(vm)->ToString(vm);
533         }
534     }
535 }
536 
Get(Local<ObjectRef> object,EcmaVM * vm)537 void Get(Local<ObjectRef> object, EcmaVM *vm)
538 {
539     GTEST_LOG_(INFO) << "Get";
540     int cnt = 1; // 1 = key
541     Local<JSValueRef> value = object->Get(vm, cnt);
542     if (value->IsString(vm)) {
543         GTEST_LOG_(INFO) << "Key:1  Value:" << value->ToString(vm)->ToString(vm);
544     }
545     value = object->Get(vm, StringRef::NewFromUtf8(vm, "Test2"));
546     if (value->IsString(vm)) {
547         GTEST_LOG_(INFO) << "Key:Test2  Value:" << value->ToString(vm)->ToString(vm);
548     }
549     value = object->Get(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"));
550     if (value->IsString(vm)) {
551         GTEST_LOG_(INFO) << "Key:AttributeKey1  Value:" << value->ToString(vm)->ToString(vm);
552     }
553     int num = 10; // 10 = randomness
554     object->Set(vm, StringRef::NewFromUtf8(vm, "Accessor1"), NumberRef::New(vm, num));
555     object->Set(vm, StringRef::NewFromUtf8(vm, "Test3"), StringRef::NewFromUtf8(vm, "Test3Value"));
556     object->Set(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"),
557         SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "AttributeKey3Value")));
558     Local<StringRef> str = object->Get(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"));
559     if (str->IsString(vm)) {
560         GTEST_LOG_(INFO) << "Key:AttributeKey3  Value:" << str->ToString(vm);
561     }
562     str = object->Get(vm, StringRef::NewFromUtf8(vm, "Accessor1"));
563     if (str->IsString(vm)) {
564         GTEST_LOG_(INFO) << "Key:Accessor1  Value:" << str->ToString(vm);
565     }
566     str = object->Get(vm, StringRef::NewFromUtf8(vm, "Test3"));
567     if (str->IsString(vm)) {
568         GTEST_LOG_(INFO) << "Key:Test3  Value:" << str->ToString(vm);
569     }
570 }
571 
SetValueAgain(Local<ObjectRef> object,EcmaVM * vm)572 void SetValueAgain(Local<ObjectRef> object, EcmaVM *vm)
573 {
574     GTEST_LOG_(INFO) << "SetValueAgain";
575     GTEST_LOG_(INFO) << "SetValueAgain";
576     int cnt = 1; // 1 = key
577     bool b = object->Set(vm, cnt, StringRef::NewFromUtf8(vm, "TestValueAgain1"));
578     ASSERT_TRUE(b);
579     b = object->Set(vm, StringRef::NewFromUtf8(vm, "Test3"), StringRef::NewFromUtf8(vm, "TestValueAgain3"));
580     ASSERT_TRUE(b);
581     b = object->Set(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"),
582         StringRef::NewFromUtf8(vm, "AttributeValueAgain1"));
583     ASSERT_TRUE(b);
584     b = object->Set(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"),
585         StringRef::NewFromUtf8(vm, "AttributeValueAgain3"));
586     ASSERT_TRUE(b);
587     b = object->Set(vm, StringRef::NewFromUtf8(vm, "Accessor1"), StringRef::NewFromUtf8(vm, "AttributeValueAgain2"));
588     ASSERT_TRUE(b);
589     GTEST_LOG_(INFO) << "GetValueAgain";
590     Get(object, vm);
591     GetProperty(object, vm);
592 }
593 
GetOwnEnumerablePropertyNames(Local<ObjectRef> object,EcmaVM * vm)594 void GetOwnEnumerablePropertyNames(Local<ObjectRef> object, EcmaVM *vm)
595 {
596     GTEST_LOG_(INFO) << "GetOwnEnumerablePropertyNames";
597     Local<ArrayRef> names = object->GetOwnEnumerablePropertyNames(vm);
598     int cnt = names->Length(vm);
599     GTEST_LOG_(INFO) << "GetOwnEnumerablePropertyNames cnt: " << cnt;
600     for (int i = 0; i < cnt; i++) {
601         Local<JSValueRef> value = ArrayRef::GetValueAt(vm, names, i);
602         if (value->IsSymbol(vm)) {
603             Local<SymbolRef> symbol = value;
604             GTEST_LOG_(INFO) << "PropertyNames: " << symbol->GetDescription(vm)->ToString(vm);
605         } else {
606             GTEST_LOG_(INFO) << "PropertyNames: " << value->ToString(vm)->ToString(vm);
607         }
608     }
609 }
610 
PrintAllProperty(Local<ObjectRef> object,EcmaVM * vm,int flag)611 void PrintAllProperty(Local<ObjectRef> object, EcmaVM *vm, int flag)
612 {
613     Local<ArrayRef> names = object->GetAllPropertyNames(vm, flag);
614     int cnt = names->Length(vm);
615     switch (flag) {
616         case 0: // 0 = NATIVE_DEFAULT
617             GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_DEFAULT: " << cnt;
618             break;
619         case 1: // 1 = NATIVE_WRITABLE
620             GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_WRITABLE: " << cnt;
621             break;
622         case 2: // 2 = NATIVE_ENUMERABLE
623             GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_ENUMERABLE: " << cnt;
624             break;
625         case 3: // 3 = NATIVE_CONFIGURABLE
626             GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_CONFIGURABLE: " << cnt;
627             break;
628         default:
629             break;
630     }
631     for (int i = 0; i < cnt; i++) {
632         Local<JSValueRef> value = ArrayRef::GetValueAt(vm, names, i);
633         if (value->IsSymbol(vm)) {
634             Local<SymbolRef> symbol = value;
635             GTEST_LOG_(INFO) << "PropertyNames: " << symbol->GetDescription(vm)->ToString(vm);
636         } else {
637             GTEST_LOG_(INFO) << "PropertyNames: " << value->ToString(vm)->ToString(vm);
638         }
639     }
640 }
641 
GetAllPropertyNames(Local<ObjectRef> object,EcmaVM * vm)642 void GetAllPropertyNames(Local<ObjectRef> object, EcmaVM *vm)
643 {
644     GTEST_LOG_(INFO) << "GetAllPropertyNames";
645     for (int i = 0; i < 4; i++) { // 4 show Go through all the properties
646         PrintAllProperty(object, vm, i);
647     }
648 }
649 
HasAndDelete(Local<ObjectRef> object,EcmaVM * vm)650 void HasAndDelete(Local<ObjectRef> object, EcmaVM *vm)
651 {
652     GTEST_LOG_(INFO) << "HasAndDelete";
653     bool b = object->Has(vm, 1); // 1 = key
654     ASSERT_TRUE(b);
655     b = object->Has(vm, StringRef::NewFromUtf8(vm, "Test2"));
656     ASSERT_TRUE(b);
657     b = object->Delete(vm, StringRef::NewFromUtf8(vm, "Test2"));
658     ASSERT_TRUE(b);
659     b = object->Has(vm, StringRef::NewFromUtf8(vm, "Test2"));
660     ASSERT_FALSE(b);
661 }
662 
FreezeAndSeal(Local<ObjectRef> object,EcmaVM * vm)663 void FreezeAndSeal(Local<ObjectRef> object, EcmaVM *vm)
664 {
665     GTEST_LOG_(INFO) << "FreezeAndSeal";
666     object->Seal(vm);
667     int num1 = 1; // 1 = key
668     int num2 = 2; // 2 = key
669     bool b = object->Set(vm, num1, StringRef::NewFromUtf8(vm, "Seal1"));
670     ASSERT_TRUE(b);
671     b = object->Delete(vm, num1);
672     ASSERT_FALSE(b);
673     b = object->Set(vm, num2, StringRef::NewFromUtf8(vm, "2"));
674     ASSERT_FALSE(b);
675     object->Freeze(vm);
676     PropertyAttribute attribute(StringRef::NewFromUtf8(vm, "FreezeValue"), true, true, false);
677     b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "Freeze"), attribute);
678     ASSERT_FALSE(b);
679     b = object->Has(vm, num2);
680     ASSERT_FALSE(b);
681     b = object->Has(vm, StringRef::NewFromUtf8(vm, "Freeze"));
682     ASSERT_FALSE(b);
683     b = object->Delete(vm, num2);
684     ASSERT_FALSE(b);
685     b = object->Delete(vm, StringRef::NewFromUtf8(vm, "Freeze"));
686     ASSERT_FALSE(b);
687 }
688 
GetOwnProperty(Local<ObjectRef> object,EcmaVM * vm)689 void GetOwnProperty(Local<ObjectRef> object, EcmaVM *vm)
690 {
691     GTEST_LOG_(INFO) << "GetOwnProperty";
692     PropertyAttribute value1;
693     bool b = object->GetOwnProperty(vm, NumberRef::New(vm, 1), value1);
694     ASSERT_TRUE(b);
695     PropertyAttribute value2;
696     b = object->GetOwnProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"), value2);
697     ASSERT_TRUE(b);
698     ASSERT_EQ(true, value2.IsWritable());
699     ASSERT_EQ(true, value2.IsEnumerable());
700     ASSERT_EQ(false, value2.IsConfigurable());
701     ASSERT_EQ(true, value2.HasWritable());
702     ASSERT_EQ(true, value2.HasConfigurable());
703     ASSERT_EQ(true, value2.HasEnumerable());
704     Local<JSValueRef> value = value2.GetValue(vm);
705     ASSERT_EQ("AttributeValue1", value->ToString(vm)->ToString(vm));
706 }
707 
708 class A {
709 public:
Test() const710     void Test() const
711     {
712         GTEST_LOG_(INFO) << "Class A Test()";
713     }
714 };
715 
NativePointer(Local<ObjectRef> object,EcmaVM * vm)716 void NativePointer(Local<ObjectRef> object, EcmaVM *vm)
717 {
718     GTEST_LOG_(INFO) << "NativePointer";
719     int cnt = 10; // 10 = accommodate quantity
720     object->SetNativePointerFieldCount(vm, cnt);
721     ASSERT_EQ(cnt, object->GetNativePointerFieldCount(vm));
722     A *a = new A();
723     int cnt2 = 1;  // 11 = random Numbers
724     int cnt3 = 11; // 1 = random Numbers
725     object->SetNativePointerField(vm, cnt2, static_cast<void *>(a), nullptr, nullptr);
726     object->SetNativePointerField(vm, cnt3, static_cast<void *>(a), nullptr, nullptr);
727     A *value1 = static_cast<A *>(object->GetNativePointerField(vm, cnt2));
728     A *value2 = static_cast<A *>(object->GetNativePointerField(vm, cnt3));
729     if (value1 == nullptr) {
730         GTEST_LOG_(INFO) << "SetNativePointerField is Error";
731     } else {
732         value1->Test();
733     }
734     if (value2 == nullptr) {
735         GTEST_LOG_(INFO) << "SetNativePointerField is OK";
736     }
737     Local<NativePointerRef> native = NativePointerRef::New(vm, static_cast<void *>(a));
738     bool b = object->ConvertToNativeBindingObject(vm, native);
739     ASSERT_TRUE(b);
740 }
741 
SetPrototype(Local<ObjectRef> object,EcmaVM * vm)742 void SetPrototype(Local<ObjectRef> object, EcmaVM *vm)
743 {
744     GTEST_LOG_(INFO) << "SetPrototype";
745     int cnt = 111; // 111 = random Numbers
746     Local<NumberRef> obj = NumberRef::New(vm, cnt);
747     object->SetPrototype(vm, obj);
748     Local<JSValueRef> type = object->GetPrototype(vm);
749     if (type->IsUndefined() || type->IsNull()) {
750         return;
751     }
752     GTEST_LOG_(INFO) << "Prototype: " << type->Typeof(vm)->ToString(vm);
753 }
754 
HWTEST_F_L0(JSNApiSampleTest,Sample_Demo3_ObjectRef)755 HWTEST_F_L0(JSNApiSampleTest, Sample_Demo3_ObjectRef)
756 {
757     GTEST_LOG_(INFO) << "SetPrototype";
758     LocalScope scope(vm_);
759     GetSymbolRef(vm_);
760     Local<SymbolRef> symbol = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "Symbol"));
761     Local<ObjectRef> object = ObjectRef::New(vm_);
762     SetPrototype(object, vm_);
763     ObjectRefSet(object, vm_, symbol);
764     GetProperty(object, vm_);
765     GetOwnProperty(object, vm_);
766     GetAllPropertyNames(object, vm_);
767     GetOwnEnumerablePropertyNames(object, vm_);
768     Get(object, vm_);
769     NativePointer(object, vm_);
770     SetValueAgain(object, vm_);
771     HasAndDelete(object, vm_);
772     FreezeAndSeal(object, vm_);
773 }
774 
775 /* demo4 无参无返回值的函数的调用。 ts:
776  * function FuncTest(): void {
777  * console.log("func test log ...");
778  * }
779  * FuncTest();
780  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo4_function_test_1)781 HWTEST_F_L0(JSNApiSampleTest, sample_demo4_function_test_1)
782 {
783     GTEST_LOG_(INFO) << "sample_demo4_function_test_1 =======================================";
784     LocalScope scope(vm_);
785 
786     Local<FunctionRef> FuncTest = FunctionRef::New(vm_, [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
787         EcmaVM *vm = runtimeInfo->GetVM();
788         LocalScope scope(vm);
789         GTEST_LOG_(INFO) << "func test log ...";
790         return JSValueRef::Undefined(vm);
791     });
792     FuncTest->Call(vm_, JSValueRef::Undefined(vm_), nullptr, 0);
793     GTEST_LOG_(INFO) << "sample_demo4_function_test_1 ==========================================";
794 }
795 
796 /* demo4 有参有返回值的函数的调用。 ts:
797  * function Add(x: number, y: number): number {
798  * return x + y;
799  * }
800  * let sum = Add(12, 34);
801  * console.log(sum);
802  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo4_function_test_2)803 HWTEST_F_L0(JSNApiSampleTest, sample_demo4_function_test_2)
804 {
805     GTEST_LOG_(INFO) << "sample_demo4_function_test_2 =======================================";
806     LocalScope scope(vm_);
807     Local<FunctionRef> Add = FunctionRef::New(vm_, [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
808         EcmaVM *vm = runtimeInfo->GetVM();
809         LocalScope scope(vm);
810         // 参数的个数。
811         uint32_t argsCount = runtimeInfo->GetArgsNumber();
812         // 遍历参数。
813         for (uint32_t i = 0; i < argsCount; ++i) {
814             Local<JSValueRef> arg = runtimeInfo->GetCallArgRef(i);
815             GTEST_LOG_(INFO) << "func test arg " << i << "   " << arg->Int32Value(vm);
816         }
817         // 获取前两个参数。
818         Local<JSValueRef> jsArg0 = runtimeInfo->GetCallArgRef(0);
819         Local<JSValueRef> jsArg1 = runtimeInfo->GetCallArgRef(1);
820         int arg0 = jsArg0->Int32Value(vm);
821         int arg1 = jsArg1->Int32Value(vm);
822         int sum = arg0 + arg1;
823         GTEST_LOG_(INFO) << "func test sum " << sum;
824         // 参数返回值
825         return NumberRef::New(vm, sum);
826     });
827     int argv0 = 12; // random number
828     int argv1 = 34; // random number
829     Local<JSValueRef> *argv = new Local<JSValueRef>[2];
830     argv[0] = NumberRef::New(vm_, argv0);
831     argv[1] = NumberRef::New(vm_, argv1);
832     Local<JSValueRef> jsSum = Add->Call(vm_, JSValueRef::Undefined(vm_), argv, 2);
833     int sum = jsSum->Int32Value(vm_);
834     GTEST_LOG_(INFO) << "func test call sum " << sum;
835     GTEST_LOG_(INFO) << "sample_demo4_function_test_2 ==========================================";
836 }
837 
AddFunc(JsiRuntimeCallInfo * runtimeInfo)838 Local<JSValueRef> AddFunc(JsiRuntimeCallInfo *runtimeInfo)
839 {
840     EcmaVM *vm = runtimeInfo->GetVM();
841     LocalScope scope(vm);
842     // 参数的个数。
843     uint32_t argsCount = runtimeInfo->GetArgsNumber();
844     // 遍历参数。
845     for (uint32_t i = 0; i < argsCount; ++i) {
846         Local<JSValueRef> arg = runtimeInfo->GetCallArgRef(i);
847         GTEST_LOG_(INFO) << "func test arg " << i << "   " << arg->Int32Value(vm);
848     }
849     // 获取前两个参数。
850     Local<JSValueRef> jsArg0 = runtimeInfo->GetCallArgRef(0);
851     Local<JSValueRef> jsArg1 = runtimeInfo->GetCallArgRef(1);
852     int arg0 = jsArg0->Int32Value(vm);
853     int arg1 = jsArg1->Int32Value(vm);
854     int sum = arg0 + arg1;
855     // 参数返回值
856     return NumberRef::New(vm, sum);
857 }
858 
AddProxyFunc(JsiRuntimeCallInfo * runtimeInfo)859 Local<JSValueRef> AddProxyFunc(JsiRuntimeCallInfo *runtimeInfo)
860 {
861     EcmaVM *vm = runtimeInfo->GetVM();
862     LocalScope scope(vm);
863     // 参数的个数。
864     uint32_t argsCount = runtimeInfo->GetArgsNumber();
865     // 函数调用的时候的传参个数,如果不能等于这个值说明函数调用有问题。
866     uint32_t defaultArgsCount = 3;
867     if (argsCount != defaultArgsCount) {
868         return NumberRef::New(vm, 0);
869     }
870     // 函数
871     int index = 0; // 获取参数的索引。
872     Local<JSValueRef> jsArg0 = runtimeInfo->GetCallArgRef(index);
873     // 获取前两个参数。
874     index++;
875     Local<JSValueRef> jsArg1 = runtimeInfo->GetCallArgRef(index);
876     index++;
877     Local<JSValueRef> jsArg2 = runtimeInfo->GetCallArgRef(index);
878     Local<FunctionRef> addFunc = jsArg0;
879     const int addFuncArgCount = 2; // 内部调用的函数的参数个数。
880     Local<JSValueRef> argv[addFuncArgCount] = { jsArg1, jsArg2 };
881     Local<JSValueRef> jsSum = addFunc->Call(vm, JSValueRef::Undefined(vm), argv, addFuncArgCount);
882     int sum = jsSum->Int32Value(vm);
883     int multiple = 2; // 代理的功能,原函数的2倍返回。
884     sum *= multiple;
885     // 参数返回值
886     return NumberRef::New(vm, sum);
887 }
888 
889 /* demo4 参数是函数的调用。 ts:
890  * function Add(x: number, y: number): number {
891  * return x + y;
892  * }
893  * function AddProxy(add: (x: number, y: number) => number, x: number, y: number) {
894  * let sum = add(x, y);
895  * return sum * 2
896  * }
897  * let sum1 = Add(12, 34);
898  * let sum2 = AddProxy(Add,12, 34);
899  * console.log(sum1);
900  * console.log(sum2);
901  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo4_function_test_3)902 HWTEST_F_L0(JSNApiSampleTest, sample_demo4_function_test_3)
903 {
904     GTEST_LOG_(INFO) << "sample_demo4_function_test_3 =======================================";
905     LocalScope scope(vm_);
906     Local<FunctionRef> Add = FunctionRef::New(vm_, AddFunc);
907     Local<FunctionRef> AddProxy = FunctionRef::New(vm_, AddProxyFunc);
908     int num1 = 12; // random number
909     int num2 = 34; // random number
910     Local<JSValueRef> addArgv[2];
911     addArgv[0] = NumberRef::New(vm_, num1);
912     addArgv[1] = NumberRef::New(vm_, num2);
913     Local<JSValueRef> addProxyArgv[3];
914     addProxyArgv[0] = Add;
915     addProxyArgv[1] = NumberRef::New(vm_, num1);
916     addProxyArgv[2] = NumberRef::New(vm_, num2);
917     Local<JSValueRef> jsSum1 = Add->Call(vm_, JSValueRef::Undefined(vm_), addArgv, 2);
918     Local<JSValueRef> jsSum2 = AddProxy->Call(vm_, JSValueRef::Undefined(vm_), addProxyArgv, 3);
919     int sum1 = jsSum1->Int32Value(vm_);
920     int sum2 = jsSum2->Int32Value(vm_);
921     GTEST_LOG_(INFO) << "func test call Add , sum = " << sum1;
922     GTEST_LOG_(INFO) << "func test call AddProxy , sum = " << sum2;
923     GTEST_LOG_(INFO) << "sample_demo4_function_test_3 ==========================================";
924 }
925 
926 /* demo5 类的静态函数和非静态函数的测试,静态变量变量 和 非静态变量的测试。 ts:
927  * class Greeter {
928  * // 静态变量。
929  * static position:string = "door";
930  * // 私有静态变量。
931  * private static standardGreetingStr:string = "Hello, there";
932  *
933  * // 私有非静态变量。
934  * private privateGreeting: string;
935  * // 非静态变量。
936  * greeting: string;
937  *
938  * // 构造函数。
939  * constructor(greet: string) {
940  * this.greeting = greet;
941  * }
942  *
943  * // 非静态函数。
944  * SetPrivateGreeting(priGreeting: string):void
945  * {
946  * this.privateGreeting = priGreeting;
947  * }
948  *
949  * // 非静态函数调用。
950  * Greet(): string {
951  * if (this.privateGreeting) {
952  * return "Hello, " + this.privateGreeting;
953  * }else if (this.greeting) {
954  * return "Hello, " + this.greeting;
955  * }
956  * else {
957  * return Greeter.standardGreetingStr;
958  * }
959  * }
960  *
961  * // 静态函数调用。
962  * static StandardGreeting(): string {
963  * return Greeter.standardGreetingStr;
964  * }
965  *
966  * // 静态函数调用。
967  * static StandardPosition(): string {
968  * return Greeter.position;
969  * }
970  *
971  * }
972  *
973  * let greeter1: Greeter = new Greeter("everyone");
974  *
975  * // 非静态函数调用
976  * console.log(greeter1.Greet());
977  *
978  * greeter1.SetPrivateGreeting("vip");
979  * console.log(greeter1.Greet());
980  *
981  * greeter1.SetPrivateGreeting("");
982  * console.log(greeter1.Greet());
983  *
984  * // 修改变量
985  * greeter1.greeting = "";
986  * console.log(greeter1.Greet());
987  *
988  * // 静态函数调用。
989  * console.log(Greeter.StandardGreeting());
990  * console.log(Greeter.StandardPosition());
991  *
992  * // 修改静态变量。
993  * Greeter.position = "house";
994  * console.log(Greeter.StandardPosition());
995  */
996 class Tag {
997 public:
Tag(const std::string name)998     explicit Tag(const std::string name) : name_(name)
999     {
1000         GTEST_LOG_(INFO) << "tag construction , name is " << name_;
1001     }
~Tag()1002     ~Tag()
1003     {
1004         GTEST_LOG_(INFO) << "tag deconstruction , name is " << name_;
1005     }
1006 
1007 private:
1008     std::string name_;
1009 };
1010 
1011 class Greeter {
1012 private:
1013     // 新建ClassFunction
1014     static Local<FunctionRef> NewClassFunction(EcmaVM *vm);
1015 
1016     // 添加静态变量。
1017     static void AddStaticVariable(EcmaVM *vm, Local<FunctionRef> &claFunc);
1018     // 添加静态函数。
1019     static void AddStaticFunction(EcmaVM *vm, Local<FunctionRef> &claFunc);
1020 
1021     // 添加非静态变量。
1022     static void AddVariable(EcmaVM *vm, Local<ObjectRef> &proto);
1023     // 添加非静态函数。
1024     static void AddFunction(EcmaVM *vm, Local<ObjectRef> &proto);
1025 
1026 public:
1027     // 获取ClassFunction
1028     static Local<FunctionRef> GetClassFunction(EcmaVM *vm);
1029     static Local<Greeter> New(EcmaVM *vm, Local<StringRef> greet);
1030 
1031     // 非静态函数调用。
1032     static void SetPrivateGreeting(EcmaVM *vm, Local<Greeter> thisRef, Local<StringRef> priGreeting);
1033     static Local<StringRef> Greet(EcmaVM *vm, Local<Greeter> thisRef);
1034 
1035     // 静态函数的调用。
1036     static Local<StringRef> StandardGreeting(EcmaVM *vm);
1037     static Local<StringRef> StandardPosition(EcmaVM *vm);
1038 
1039 private:
1040     static Local<SymbolRef> standardGreetingStrKey;
1041     static Local<SymbolRef> privateGreetingKey;
1042 
1043     // 类名
1044     const static std::string CLASS_NAME;
1045 };
1046 
1047 Local<SymbolRef> Greeter::standardGreetingStrKey;
1048 Local<SymbolRef> Greeter::privateGreetingKey;
1049 
1050 const std::string Greeter::CLASS_NAME = "GreeterClass";
1051 
NewClassFunction(EcmaVM * vm)1052 Local<FunctionRef> Greeter::NewClassFunction(EcmaVM *vm)
1053 {
1054     // 初始化私有静态变量的key。
1055     Greeter::standardGreetingStrKey = SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "standardGreetingStr"));
1056     Greeter::privateGreetingKey = SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "privateGreeting"));
1057 
1058     Tag *tag = new Tag("ClassFunctionTag");
1059     Local<FunctionRef> claFunc = FunctionRef::NewClassFunction(
1060         vm,
1061         // 构造函数调用
1062         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1063             EcmaVM *vm = runtimeInfo->GetVM();
1064             LocalScope scope(vm);
1065             // 获取this
1066             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1067             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1068             // 获取参数。
1069             Local<JSValueRef> greet = runtimeInfo->GetCallArgRef(0);
1070             // ts: this.greeting = greet;
1071             thisRef->Set(vm, StringRef::NewFromUtf8(vm, "greeting"), greet);
1072             return thisRef;
1073         },
1074         [](void *env, void *nativePointer, void *data) {
1075             GTEST_LOG_(INFO) << "NewClassFunction, nativePointer is " << nativePointer;
1076             Tag *t = static_cast<Tag *>(data);
1077             delete t;
1078         },
1079         tag);
1080     // static 添加 到  claFunc。
1081     // 添加静态变量。
1082     AddStaticVariable(vm, claFunc);
1083     // 添加静态函数
1084     AddStaticFunction(vm, claFunc);
1085     Local<JSValueRef> jsProto = claFunc->GetFunctionPrototype(vm);
1086     Local<ObjectRef> proto = jsProto->ToObject(vm);
1087     // 非static 添加到 proto。
1088     // 添加非静态变量
1089     AddVariable(vm, proto);
1090     // 添加非静态函数
1091     AddFunction(vm, proto);
1092     // 设置类名。
1093     claFunc->SetName(vm, StringRef::NewFromUtf8(vm, Greeter::CLASS_NAME.c_str()));
1094     return claFunc;
1095 }
1096 
GetClassFunction(EcmaVM * vm)1097 Local<FunctionRef> Greeter::GetClassFunction(EcmaVM *vm)
1098 {
1099     Local<ObjectRef> globalObj = JSNApi::GetGlobalObject(vm);
1100     Local<JSValueRef> jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, Greeter::CLASS_NAME.c_str()));
1101     if (jsClaFunc->IsFunction(vm)) {
1102         return jsClaFunc;
1103     }
1104     Local<FunctionRef> claFunc = Greeter::NewClassFunction(vm);
1105     // 添加到全局。
1106     globalObj->Set(vm, claFunc->GetName(vm), claFunc);
1107     return claFunc;
1108 }
1109 
1110 // 添加静态变量。
AddStaticVariable(EcmaVM * vm,Local<FunctionRef> & claFunc)1111 void Greeter::AddStaticVariable(EcmaVM *vm, Local<FunctionRef> &claFunc)
1112 {
1113     // 静态变量。
1114     // static position:string = "door";
1115     claFunc->Set(vm, StringRef::NewFromUtf8(vm, "position"), StringRef::NewFromUtf8(vm, "door"));
1116     // 私有静态变量。
1117     // private static standardGreetingStr:string = "Hello, there";
1118     claFunc->Set(vm, Greeter::standardGreetingStrKey, StringRef::NewFromUtf8(vm, "Hello, there"));
1119 }
1120 
1121 // 添加静态函数。
AddStaticFunction(EcmaVM * vm,Local<FunctionRef> & claFunc)1122 void Greeter::AddStaticFunction(EcmaVM *vm, Local<FunctionRef> &claFunc)
1123 {
1124     // 静态函数调用。
1125     claFunc->Set(vm, StringRef::NewFromUtf8(vm, "StandardGreeting"),
1126         FunctionRef::New(vm,
1127         // 函数体
1128         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1129             EcmaVM *vm = runtimeInfo->GetVM();
1130             LocalScope scope(vm);
1131             Local<FunctionRef> claFunc = Greeter::GetClassFunction(vm);
1132             Local<JSValueRef> jsStandardGreetingStr = claFunc->Get(vm, Greeter::standardGreetingStrKey);
1133             return jsStandardGreetingStr;
1134         }));
1135     // 静态函数调用。
1136     claFunc->Set(vm, StringRef::NewFromUtf8(vm, "StandardPosition"),
1137         FunctionRef::New(vm,
1138         // 函数体
1139         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1140             EcmaVM *vm = runtimeInfo->GetVM();
1141             LocalScope scope(vm);
1142             Local<FunctionRef> claFunc = Greeter::GetClassFunction(vm);
1143             Local<JSValueRef> jsPosition = claFunc->Get(vm, StringRef::NewFromUtf8(vm, "position"));
1144             return jsPosition;
1145         }));
1146 }
1147 
1148 // 添加非静态变量。
AddVariable(EcmaVM * vm,Local<ObjectRef> & proto)1149 void Greeter::AddVariable(EcmaVM *vm, Local<ObjectRef> &proto)
1150 {
1151     // 私有非静态变量。
1152     proto->Set(vm, Greeter::privateGreetingKey, JSValueRef::Undefined(vm));
1153     // 非静态变量。
1154     proto->Set(vm, StringRef::NewFromUtf8(vm, "greeting"), JSValueRef::Undefined(vm));
1155 }
1156 
1157 // 添加非静态函数。
AddFunction(EcmaVM * vm,Local<ObjectRef> & proto)1158 void Greeter::AddFunction(EcmaVM *vm, Local<ObjectRef> &proto)
1159 {
1160     // 非静态函数。
1161     proto->Set(vm, StringRef::NewFromUtf8(vm, "SetPrivateGreeting"),
1162         FunctionRef::New(vm,
1163         // 函数体
1164         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1165             EcmaVM *vm = runtimeInfo->GetVM();
1166             LocalScope scope(vm);
1167             // 获取this
1168             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1169             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1170             // 获取参数。
1171             Local<JSValueRef> priGreeting = runtimeInfo->GetCallArgRef(0);
1172             thisRef->Set(vm, Greeter::privateGreetingKey, priGreeting);
1173             return JSValueRef::Undefined(vm);
1174         }));
1175     // 非静态函数。
1176     proto->Set(vm, StringRef::NewFromUtf8(vm, "Greet"),
1177         FunctionRef::New(vm,
1178         // 函数体
1179         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1180             EcmaVM *vm = runtimeInfo->GetVM();
1181             LocalScope scope(vm);
1182             // 获取类
1183             Local<FunctionRef> claFunc = Greeter::GetClassFunction(vm);
1184             // 获取this
1185             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1186             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1187             Local<JSValueRef> jsPrivateGreeting = thisRef->Get(vm, Greeter::privateGreetingKey);
1188             Local<JSValueRef> jsGreeting = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "greeting"));
1189             Local<JSValueRef> jsStandardGreetingStr = claFunc->Get(vm, Greeter::standardGreetingStrKey);
1190             std::string ret;
1191             if (jsPrivateGreeting->IsString(vm)) {
1192                 ret.append("Hello, ").append(jsPrivateGreeting->ToString(vm)->ToString(vm));
1193             } else if (jsGreeting->IsString(vm)) {
1194                 ret.append("Hello, ").append(jsGreeting->ToString(vm)->ToString(vm));
1195             } else {
1196                 ret.append(jsStandardGreetingStr->ToString(vm)->ToString(vm));
1197             }
1198             return StringRef::NewFromUtf8(vm, ret.c_str(), ret.size());
1199         }));
1200 }
1201 
New(EcmaVM * vm,Local<StringRef> greet)1202 Local<Greeter> Greeter::New(EcmaVM *vm, Local<StringRef> greet)
1203 {
1204     // 获取类函数。
1205     Local<FunctionRef> claFunc = Greeter::GetClassFunction(vm);
1206     // 定义参数。
1207     Local<JSValueRef> argv[1] = {greet};
1208     // 构造函数,构造对象。
1209     Local<JSValueRef> jsObj = claFunc->Constructor(vm, argv, 1);
1210     Local<ObjectRef> obj = jsObj->ToObject(vm);
1211     return obj;
1212 }
1213 
1214 /* // 非静态函数调用。 ts:
1215  * SetPrivateGreeting(priGreeting: string):void
1216  */
SetPrivateGreeting(EcmaVM * vm,Local<Greeter> thisRef,Local<StringRef> priGreeting)1217 void Greeter::SetPrivateGreeting(EcmaVM *vm, Local<Greeter> thisRef, Local<StringRef> priGreeting)
1218 {
1219     Local<ObjectRef> objRef = thisRef;
1220     Local<FunctionRef> func = objRef->Get(vm, StringRef::NewFromUtf8(vm, "SetPrivateGreeting"));
1221     Local<JSValueRef> argv [1] = {priGreeting};
1222     func->Call(vm, objRef, argv, 1);
1223 }
1224 
1225 /* // 非静态函数调用。 ts:
1226  * Greet(): string
1227  */
Greet(EcmaVM * vm,Local<Greeter> thisRef)1228 Local<StringRef> Greeter::Greet(EcmaVM *vm, Local<Greeter> thisRef)
1229 {
1230     Local<ObjectRef> objRef = thisRef;
1231     Local<FunctionRef> func = objRef->Get(vm, StringRef::NewFromUtf8(vm, "Greet"));
1232     return func->Call(vm, objRef, nullptr, 0);
1233 }
1234 
1235 /* // 静态函数的调用。 ts:
1236  * static StandardGreeting(): string
1237  */
StandardGreeting(EcmaVM * vm)1238 Local<StringRef> Greeter::StandardGreeting(EcmaVM *vm)
1239 {
1240     // 获取类函数。
1241     Local<FunctionRef> claFunc = Greeter::GetClassFunction(vm);
1242     // 获取函数
1243     Local<FunctionRef> func = claFunc->Get(vm, StringRef::NewFromUtf8(vm, "StandardGreeting"));
1244     // 调用函数
1245     return func->Call(vm, JSValueRef::Undefined(vm), nullptr, 0);
1246 }
1247 
1248 /* // 静态函数的调用。ts:
1249  * static StandardPosition(): string
1250  */
StandardPosition(EcmaVM * vm)1251 Local<StringRef> Greeter::StandardPosition(EcmaVM *vm)
1252 {
1253     // 获取类函数。
1254     Local<FunctionRef> claFunc = Greeter::GetClassFunction(vm);
1255     // 获取函数
1256     Local<FunctionRef> func = claFunc->Get(vm, StringRef::NewFromUtf8(vm, "StandardPosition"));
1257     // 调用函数
1258     return func->Call(vm, JSValueRef::Undefined(vm), nullptr, 0);
1259 }
1260 
1261 /* 类的调用测试: ts:
1262  * let greeter1: Greeter = new Greeter("everyone");
1263  *
1264  * // 非静态函数调用
1265  * console.log(greeter1.Greet());
1266  *
1267  * greeter1.SetPrivateGreeting("vip");
1268  * console.log(greeter1.Greet());
1269  *
1270  * greeter1.SetPrivateGreeting("");
1271  * console.log(greeter1.Greet());
1272  *
1273  * // 修改变量
1274  * greeter1.greeting = "";
1275  * console.log(greeter1.Greet());
1276  *
1277  * // 静态函数调用。
1278  * console.log(Greeter.StandardGreeting());
1279  * console.log(Greeter.StandardPosition());
1280  *
1281  * // 修改静态变量。
1282  * Greeter.position = "house";
1283  * console.log(Greeter.StandardPosition());
1284  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo5_class_test)1285 HWTEST_F_L0(JSNApiSampleTest, sample_demo5_class_test)
1286 {
1287     GTEST_LOG_(INFO) << "sample_demo5_class_test =======================================";
1288     LocalScope scope(vm_);
1289     Local<Greeter> greeter1 = Greeter::New(vm_, StringRef::NewFromUtf8(vm_, "everyone"));
1290     // 非静态函数调用
1291     GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_);
1292     Greeter::SetPrivateGreeting(vm_, greeter1, StringRef::NewFromUtf8(vm_, "vip"));
1293     GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_);
1294     Greeter::SetPrivateGreeting(vm_, greeter1, JSValueRef::Undefined(vm_));
1295     GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_);
1296     // 修改变量
1297     Local<ObjectRef> objRef1 = greeter1;
1298     objRef1->Set(vm_, StringRef::NewFromUtf8(vm_, "greeting"), JSValueRef::Undefined(vm_));
1299     GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_);
1300 
1301     // 静态函数调用。
1302     GTEST_LOG_(INFO) << Greeter::StandardGreeting(vm_)->ToString(vm_);
1303     GTEST_LOG_(INFO) << Greeter::StandardPosition(vm_)->ToString(vm_);
1304 
1305     // 修改静态变量。
1306     Local<FunctionRef> classFunc = Greeter::GetClassFunction(vm_);
1307     classFunc->Set(vm_, StringRef::NewFromUtf8(vm_, "position"), StringRef::NewFromUtf8(vm_, "house"));
1308 
1309     GTEST_LOG_(INFO) << Greeter::StandardPosition(vm_)->ToString(vm_);
1310     GTEST_LOG_(INFO) << "sample_demo5_class_test =======================================";
1311 }
1312 
1313 /* demo6 多态 ts:
1314  * // 基类
1315  * class Derive {
1316  * baseNum: number = 1
1317  * constructor(num: number){
1318  * this.baseNum = num
1319  * }
1320  * Compute(): number {
1321  * return this.baseNum
1322  * }
1323  * }
1324  * // 子类1
1325  * class DeriveDouble extends Derive {
1326  * constructor(num: number){
1327  * super(num);
1328  * }
1329  * Compute() : number {
1330  * return this.baseNum * 2
1331  * }
1332  * }
1333  * // 子类2
1334  * class DerivedTriple extends Derive {
1335  * constructor(num: number){
1336  * super(num);
1337  * }
1338  * Compute() : number {
1339  * return this.baseNum * 3
1340  * }
1341  * }
1342  *
1343  * // 测试:
1344  * let d1: Derive;
1345  * let d2: Derive;
1346  * let d3: Derive;
1347  * d1 = new Derive(5);//新建基类。
1348  * d2 = new DeriveDouble(5);//新建子类。
1349  * d3 = new DerivedTriple(5);//新建子类。
1350  * let i1:number = d1.Compute();
1351  * let i2:number = d2.Compute();
1352  * let i3:number = d3.Compute();
1353  * console.log(i1);
1354  * console.log(i2);
1355  * console.log(i3);
1356  */
1357 
1358 /* 基类 ts:
1359  * class Derive {
1360  * baseNum: number = 1
1361  * constructor(num: number){
1362  * this.baseNum = num
1363  * }
1364  * Compute(): number {
1365  * return this.baseNum
1366  * }
1367  * }
1368  */
1369 class Derive {
1370 private:
1371     // 新建ClassFunction
1372     static Local<FunctionRef> NewClassFunction(EcmaVM *vm);
1373 
1374 public:
1375     // 获取ClassFunction
1376     static Local<FunctionRef> GetClassFunction(EcmaVM *vm);
1377     static Local<Derive> New(EcmaVM *vm, Local<NumberRef> num);
1378 
1379     static Local<NumberRef> Compute(EcmaVM *vm, Local<Derive> thisRef);
1380 
1381 private:
1382     const static std::string CLASS_NAME;
1383 };
1384 
1385 const std::string Derive::CLASS_NAME = "DeriveClass";
1386 
NewClassFunction(EcmaVM * vm)1387 Local<FunctionRef> Derive::NewClassFunction(EcmaVM *vm)
1388 {
1389     Local<FunctionRef> claFunc = FunctionRef::NewClassFunction(
1390         vm,
1391         // 构造函数调用
1392         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1393             EcmaVM *vm = runtimeInfo->GetVM();
1394             LocalScope scope(vm);
1395             // 获取this
1396             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1397             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1398             // 获取参数。
1399             Local<JSValueRef> num = runtimeInfo->GetCallArgRef(0);
1400             // this.baseNum = num
1401             thisRef->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), num);
1402             return thisRef;
1403         },
1404         nullptr, nullptr);
1405     Local<JSValueRef> jsProto = claFunc->GetFunctionPrototype(vm);
1406     Local<ObjectRef> proto = jsProto->ToObject(vm);
1407     // 添加非静态变量
1408     proto->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), NumberRef::New(vm, 1));
1409     // 添加非静态函数
1410     proto->Set(vm, StringRef::NewFromUtf8(vm, "Compute"),
1411         FunctionRef::New(vm,
1412         // 函数体
1413         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1414             EcmaVM *vm = runtimeInfo->GetVM();
1415             LocalScope scope(vm);
1416 
1417             // 获取this
1418             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1419             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1420 
1421             Local<JSValueRef> jsNum = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "baseNum"));
1422             int num = jsNum->Int32Value(vm);
1423             return NumberRef::New(vm, num);
1424         }));
1425     // 设置类名。
1426     claFunc->SetName(vm, StringRef::NewFromUtf8(vm, Derive::CLASS_NAME.c_str()));
1427     return claFunc;
1428 }
1429 
GetClassFunction(EcmaVM * vm)1430 Local<FunctionRef> Derive::GetClassFunction(EcmaVM *vm)
1431 {
1432     Local<ObjectRef> globalObj = JSNApi::GetGlobalObject(vm);
1433     Local<JSValueRef> jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, Derive::CLASS_NAME.c_str()));
1434     if (jsClaFunc->IsFunction(vm)) {
1435         return jsClaFunc;
1436     }
1437     Local<FunctionRef> claFunc = Derive::NewClassFunction(vm);
1438     // 添加到全局。
1439     globalObj->Set(vm, claFunc->GetName(vm), claFunc);
1440     return claFunc;
1441 }
1442 
New(EcmaVM * vm,Local<NumberRef> num)1443 Local<Derive> Derive::New(EcmaVM *vm, Local<NumberRef> num)
1444 {
1445     // 获取类函数。
1446     Local<FunctionRef> claFunc = Derive::GetClassFunction(vm);
1447     // 定义参数。
1448     Local<JSValueRef> argv[1] = {num};
1449     // 构造函数,构造对象。
1450     Local<JSValueRef> jsObj = claFunc->Constructor(vm, argv, 1);
1451     Local<ObjectRef> obj = jsObj->ToObject(vm);
1452     return obj;
1453 }
1454 
Compute(EcmaVM * vm,Local<Derive> thisRef)1455 Local<NumberRef> Derive::Compute(EcmaVM *vm, Local<Derive> thisRef)
1456 {
1457     Local<ObjectRef> objRef = thisRef;
1458     Local<FunctionRef> func = objRef->Get(vm, StringRef::NewFromUtf8(vm, "Compute"));
1459     return func->Call(vm, objRef, nullptr, 0);
1460 }
1461 
1462 /* 子类1 ts:
1463  * class DeriveDouble extends Base {
1464  * constructor(num: number){
1465  * super(num);
1466  * }
1467  * Compute() : number {
1468  * return this.baseNum * 2
1469  * }
1470  * }
1471  */
1472 class DeriveDouble : public Derive {
1473 private:
1474     DeriveDouble() = default;
1475     // 新建ClassFunction
1476     static Local<FunctionRef> NewClassFunction(EcmaVM *vm);
1477 
1478 public:
1479     // 获取ClassFunction
1480     static Local<FunctionRef> GetClassFunction(EcmaVM *vm);
1481     static Local<DeriveDouble> New(EcmaVM *vm, Local<NumberRef> num);
1482     ~DeriveDouble() = default;
1483 
1484 public:
1485     // 设置类名
1486     const static std::string CLASS_NAME;
1487 };
1488 
1489 const std::string DeriveDouble::CLASS_NAME = "DeriveDoubleClass";
1490 
NewClassFunction(EcmaVM * vm)1491 Local<FunctionRef> DeriveDouble::NewClassFunction(EcmaVM *vm)
1492 {
1493     Local<FunctionRef> claFunc = FunctionRef::NewClassFunction(
1494         vm,
1495         // 构造函数调用
1496         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1497             EcmaVM *vm = runtimeInfo->GetVM();
1498             LocalScope scope(vm);
1499             // 获取参数。
1500             Local<JSValueRef> num = runtimeInfo->GetCallArgRef(0);
1501             // 获取this
1502             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1503             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1504             // 修改父类。
1505             thisRef->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), num);
1506             return thisRef;
1507         },
1508         nullptr, nullptr);
1509     // 设置类名。
1510     claFunc->SetName(vm, StringRef::NewFromUtf8(vm, DeriveDouble::CLASS_NAME.c_str()));
1511 
1512     // 添加非静态函数
1513     Local<ObjectRef> proto = claFunc->GetFunctionPrototype(vm)->ToObject(vm);
1514     proto->Set(vm, StringRef::NewFromUtf8(vm, "Compute"),
1515         FunctionRef::New(vm,
1516         // 函数体
1517         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1518             EcmaVM *vm = runtimeInfo->GetVM();
1519             LocalScope scope(vm);
1520             // 获取this
1521             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1522             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1523             Local<JSValueRef> jsNum = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "baseNum"));
1524             int num = jsNum->Int32Value(vm);
1525             int multiple = 2; // 函数功能,2倍返回。
1526             num *= multiple;
1527             return NumberRef::New(vm, num);
1528         }));
1529     // 父类。
1530     Local<FunctionRef> claFuncBase = Derive::GetClassFunction(vm);
1531     // 继承。
1532     claFunc->Inherit(vm, claFuncBase);
1533     return claFunc;
1534 }
1535 
GetClassFunction(EcmaVM * vm)1536 Local<FunctionRef> DeriveDouble::GetClassFunction(EcmaVM *vm)
1537 {
1538     Local<ObjectRef> globalObj = JSNApi::GetGlobalObject(vm);
1539     Local<JSValueRef> jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, DeriveDouble::CLASS_NAME.c_str()));
1540     if (jsClaFunc->IsFunction(vm)) {
1541         return jsClaFunc;
1542     }
1543     Local<FunctionRef> claFunc = DeriveDouble::NewClassFunction(vm);
1544     globalObj->Set(vm, claFunc->GetName(vm), claFunc);
1545     return claFunc;
1546 }
1547 
New(EcmaVM * vm,Local<NumberRef> num)1548 Local<DeriveDouble> DeriveDouble::New(EcmaVM *vm, Local<NumberRef> num)
1549 {
1550     // 获取类函数。
1551     Local<FunctionRef> claFunc = DeriveDouble::GetClassFunction(vm);
1552     // 定义参数。
1553     Local<JSValueRef> argv[1] = {num};
1554     // 构造函数,构造对象。
1555     Local<JSValueRef> jsObj = claFunc->Constructor(vm, argv, 1);
1556     Local<ObjectRef> obj = jsObj->ToObject(vm);
1557     return obj;
1558 }
1559 
1560 /* 子类2 ts:
1561  * class DerivedTriple extends Derive {
1562  * constructor(num: number){
1563  * super(num);
1564  * }
1565  * Compute() : number {
1566  * return this.baseNum * 3
1567  * }
1568  * }
1569  */
1570 class DerivedTriple : public Derive {
1571 private:
1572     DerivedTriple() = default;
1573     // 新建ClassFunction
1574     static Local<FunctionRef> NewClassFunction(EcmaVM *vm);
1575 
1576 public:
1577     // 获取ClassFunction
1578     static Local<FunctionRef> GetClassFunction(EcmaVM *vm);
1579     static Local<DerivedTriple> New(EcmaVM *vm, Local<NumberRef> num);
1580     ~DerivedTriple() = default;
1581 
1582 public:
1583     // 设置类名
1584     const static std::string CLASS_NAME;
1585 };
1586 
1587 const std::string DerivedTriple::CLASS_NAME = "DerivedTripleClass";
1588 
NewClassFunction(EcmaVM * vm)1589 Local<FunctionRef> DerivedTriple::NewClassFunction(EcmaVM *vm)
1590 {
1591     Local<FunctionRef> claFunc = FunctionRef::NewClassFunction(
1592         vm,
1593         // 构造函数调用
1594         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1595             EcmaVM *vm = runtimeInfo->GetVM();
1596             LocalScope scope(vm);
1597             // 获取参数。
1598             Local<JSValueRef> num = runtimeInfo->GetCallArgRef(0);
1599             // 获取this
1600             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1601             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1602             // 修改父类。
1603             thisRef->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), num);
1604             return thisRef;
1605         },
1606         nullptr, nullptr);
1607     // 设置类名。
1608     claFunc->SetName(vm, StringRef::NewFromUtf8(vm, DerivedTriple::CLASS_NAME.c_str()));
1609 
1610     // 添加非静态函数
1611     Local<ObjectRef> proto = claFunc->GetFunctionPrototype(vm)->ToObject(vm);
1612     proto->Set(vm, StringRef::NewFromUtf8(vm, "Compute"),
1613         FunctionRef::New(vm,
1614         // 函数体
1615         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1616             EcmaVM *vm = runtimeInfo->GetVM();
1617             LocalScope scope(vm);
1618             // 获取this
1619             Local<JSValueRef> jsThisRef = runtimeInfo->GetThisRef();
1620             Local<ObjectRef> thisRef = jsThisRef->ToObject(vm);
1621             Local<JSValueRef> jsNum = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "baseNum"));
1622             int num = jsNum->Int32Value(vm);
1623             int multiple = 3; // 函数功能,3倍返回。
1624             num *= multiple;
1625             return NumberRef::New(vm, num);
1626         }));
1627     // 父类。
1628     Local<FunctionRef> claFuncBase = Derive::GetClassFunction(vm);
1629     // 继承。
1630     claFunc->Inherit(vm, claFuncBase);
1631     return claFunc;
1632 }
1633 
GetClassFunction(EcmaVM * vm)1634 Local<FunctionRef> DerivedTriple::GetClassFunction(EcmaVM *vm)
1635 {
1636     Local<ObjectRef> globalObj = JSNApi::GetGlobalObject(vm);
1637     Local<JSValueRef> jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, DerivedTriple::CLASS_NAME.c_str()));
1638     if (jsClaFunc->IsFunction(vm)) {
1639         return jsClaFunc;
1640     }
1641     Local<FunctionRef> claFunc = DerivedTriple::NewClassFunction(vm);
1642     globalObj->Set(vm, claFunc->GetName(vm), claFunc);
1643     return claFunc;
1644 }
1645 
New(EcmaVM * vm,Local<NumberRef> num)1646 Local<DerivedTriple> DerivedTriple::New(EcmaVM *vm, Local<NumberRef> num)
1647 {
1648     // 获取类函数。
1649     Local<FunctionRef> claFunc = DerivedTriple::GetClassFunction(vm);
1650     // 定义参数。
1651     Local<JSValueRef> argv[1] = {num};
1652     // 构造函数,构造对象。
1653     Local<JSValueRef> jsObj = claFunc->Constructor(vm, argv, 1);
1654     Local<ObjectRef> obj = jsObj->ToObject(vm);
1655     return obj;
1656 }
1657 
1658 /* 测试。ts:
1659  * let d1: Derive;
1660  * let d2: Derive;
1661  * let d3: Derive;
1662  * d1 = new Derive(5);//新建基类。
1663  * d2 = new DeriveDouble(5);//新建子类。
1664  * d3 = new DerivedTriple(5);//新建子类。
1665  * let i1:number = d1.Compute();
1666  * let i2:number = d2.Compute();
1667  * let i3:number = d3.Compute();
1668  * console.log(i1);
1669  * console.log(i2);
1670  * console.log(i3);
1671  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo6_polymorphic_test)1672 HWTEST_F_L0(JSNApiSampleTest, sample_demo6_polymorphic_test)
1673 {
1674     GTEST_LOG_(INFO) << "sample_demo6_polymorphic_test =======================================";
1675     LocalScope scope(vm_);
1676 
1677     int num = 5;
1678 
1679     Local<Derive> d1 = Derive::New(vm_, NumberRef::New(vm_, num));
1680     Local<Derive> d2 = DeriveDouble::New(vm_, NumberRef::New(vm_, num));
1681     Local<Derive> d3 = DerivedTriple::New(vm_, NumberRef::New(vm_, num));
1682 
1683     Local<NumberRef> i1 = Derive::Compute(vm_, d1);
1684     Local<NumberRef> i2 = Derive::Compute(vm_, d2);
1685     Local<NumberRef> i3 = Derive::Compute(vm_, d3);
1686 
1687     GTEST_LOG_(INFO) << "i1 = " << i1->Int32Value(vm_);
1688     GTEST_LOG_(INFO) << "i2 = " << i2->Int32Value(vm_);
1689     GTEST_LOG_(INFO) << "i3 = " << i3->Int32Value(vm_);
1690 
1691     GTEST_LOG_(INFO) << "sample_demo6_polymorphic_test =======================================";
1692 }
1693 
1694 /* demo7 数组的使用 */
HWTEST_F_L0(JSNApiSampleTest,sample_ArrayRef_Int)1695 HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_Int)
1696 {
1697     LocalScope scope(vm_);
1698     uint32_t length = 5; // array length = 5
1699     Local<ArrayRef> arrayObject = ArrayRef::New(vm_, length);
1700     uint32_t arrayLength = arrayObject->Length(vm_);
1701     uint32_t index = 1; // array index = 0
1702     for (int i = 0; i < (int)arrayLength; i++) {
1703         Local<IntegerRef> intValue = IntegerRef::New(vm_, i * 10);
1704         ArrayRef::SetValueAt(vm_, arrayObject, i, intValue);
1705         GTEST_LOG_(INFO) << "sample_setIntValue_index_" << i << ": " << intValue->Value();
1706     }
1707     Local<IntegerRef> resultInt = ArrayRef::GetValueAt(vm_, arrayObject, index);
1708     GTEST_LOG_(INFO) << "sample_getIntValue_index_1: " << resultInt->Value();
1709     int inputInt = 99; // int data = 99
1710     Local<IntegerRef> intValue = IntegerRef::New(vm_, inputInt);
1711     bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, intValue);
1712     GTEST_LOG_(INFO) << "sample_setIntValue_index_5: " << intValue->Value() << " setResult: " << setResult;
1713     int changedInt = 66; // change data = 66
1714     Local<IntegerRef> changedIntValue = IntegerRef::New(vm_, changedInt);
1715     ArrayRef::SetValueAt(vm_, arrayObject, index, changedIntValue);
1716     GTEST_LOG_(INFO) << "sample_changedIntValue_index_1: " << changedIntValue->Value();
1717     Local<IntegerRef> resultChangedInt = ArrayRef::GetValueAt(vm_, arrayObject, index);
1718     GTEST_LOG_(INFO) << "sample_getChangedIntValue_index_1: " << resultChangedInt->Value();
1719     for (int i = 0; i < (int)arrayLength; i++) {
1720         Local<IntegerRef> printInt = ArrayRef::GetValueAt(vm_, arrayObject, i);
1721         GTEST_LOG_(INFO) << "sample_printIntValue_index_" << i << ": " << printInt->Value();
1722     }
1723 }
1724 
HWTEST_F_L0(JSNApiSampleTest,sample_ArrayRef_Bool)1725 HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_Bool)
1726 {
1727     LocalScope scope(vm_);
1728     uint32_t length = 5; // array length = 5
1729     Local<ArrayRef> arrayObject = ArrayRef::New(vm_, length);
1730     uint32_t arrayLength = arrayObject->Length(vm_);
1731     bool inputBool = true; // bool data = true
1732     uint32_t index = 0;    // array index = 0
1733     Local<BooleanRef> boolValue = BooleanRef::New(vm_, inputBool);
1734     for (int i = 0; i < (int)arrayLength; i++) {
1735         ArrayRef::SetValueAt(vm_, arrayObject, i, boolValue);
1736         GTEST_LOG_(INFO) << "sample_setBoolValue_index_" << i << ": " << boolValue->Value();
1737     }
1738     Local<BooleanRef> resultBool = ArrayRef::GetValueAt(vm_, arrayObject, index);
1739     GTEST_LOG_(INFO) << "sample_getBoolValue_index_0: " << resultBool->Value();
1740     bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, boolValue);
1741     GTEST_LOG_(INFO) << "sample_setBoolValue_index_5: " << boolValue->Value() << " setResult: " << setResult;
1742     bool changedBool = false; // change data = false
1743     Local<BooleanRef> changedBoolValue = BooleanRef::New(vm_, changedBool);
1744     ArrayRef::SetValueAt(vm_, arrayObject, index, changedBoolValue);
1745     GTEST_LOG_(INFO) << "sample_changedBoolValue_index_0: " << changedBoolValue->Value();
1746     Local<BooleanRef> resultChangedBool = ArrayRef::GetValueAt(vm_, arrayObject, index);
1747     GTEST_LOG_(INFO) << "sample_getChangedBoolValue_index_0: " << resultChangedBool->Value();
1748     for (int i = 0; i < (int)arrayLength; i++) {
1749         Local<BooleanRef> printBool = ArrayRef::GetValueAt(vm_, arrayObject, i);
1750         GTEST_LOG_(INFO) << "sample_printBoolValue_index_" << i << ": " << printBool->Value();
1751     }
1752 }
1753 
HWTEST_F_L0(JSNApiSampleTest,sample_ArrayRef_Number)1754 HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_Number)
1755 {
1756     LocalScope scope(vm_);
1757     uint32_t length = 5; // array length = 5
1758     Local<ArrayRef> arrayObject = ArrayRef::New(vm_, length);
1759     uint32_t arrayLength = arrayObject->Length(vm_);
1760     uint32_t inputNumber = 40; // number data = 40
1761     uint32_t index = 0;        // array index = 0
1762     Local<NumberRef> numberValue = NumberRef::New(vm_, inputNumber);
1763     for (int i = 0; i < (int)arrayLength; i++) {
1764         ArrayRef::SetValueAt(vm_, arrayObject, i, numberValue);
1765         GTEST_LOG_(INFO) << "sample_setNumberValue_index_" << i << ": " << numberValue->Value();
1766     }
1767     Local<NumberRef> resultNumber = ArrayRef::GetValueAt(vm_, arrayObject, index);
1768     GTEST_LOG_(INFO) << "sample_getNumberValue_index_0: " << resultNumber->Value();
1769     bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, numberValue);
1770     GTEST_LOG_(INFO) << "sample_setNumberValue_index_5: " << numberValue->Value() << " setResult: " << setResult;
1771     uint32_t changedNumber = 50; // change data = 50
1772     Local<NumberRef> changedNumberValue = NumberRef::New(vm_, changedNumber);
1773     ArrayRef::SetValueAt(vm_, arrayObject, index, changedNumberValue);
1774     GTEST_LOG_(INFO) << "sample_changedNumberValue_index_0: " << changedNumberValue->Value();
1775     Local<NumberRef> resultChangedNumber = ArrayRef::GetValueAt(vm_, arrayObject, index);
1776     GTEST_LOG_(INFO) << "sample_getChangedNumberValue_index_0: " << resultChangedNumber->Value();
1777     for (int i = 0; i < (int)arrayLength; i++) {
1778         Local<NumberRef> printNumber = ArrayRef::GetValueAt(vm_, arrayObject, i);
1779         GTEST_LOG_(INFO) << "sample_printNumberValue_index_" << i << ": " << printNumber->Value();
1780     }
1781 }
1782 
HWTEST_F_L0(JSNApiSampleTest,sample_ArrayRef_String)1783 HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_String)
1784 {
1785     LocalScope scope(vm_);
1786     uint32_t length = 5; // array length = 5
1787     Local<ArrayRef> arrayObject = ArrayRef::New(vm_, length);
1788     uint32_t arrayLength = arrayObject->Length(vm_);
1789     std::string inputString = "Sample Test";
1790     uint32_t index = 0; // array index = 0
1791     Local<StringRef> stringValue = StringRef::NewFromUtf8(vm_, inputString.c_str());
1792     for (int i = 0; i < (int)arrayLength; i++) {
1793         ArrayRef::SetValueAt(vm_, arrayObject, i, stringValue);
1794         char setBuffer[20];
1795         stringValue->WriteUtf8(vm_, setBuffer, inputString.length());
1796         std::string result(setBuffer);
1797         GTEST_LOG_(INFO) << "sample_setStringValue_index_" << i << ": " << result;
1798         memset_s(setBuffer, sizeof(setBuffer), 0, sizeof(setBuffer));
1799     }
1800     Local<StringRef> resultString = ArrayRef::GetValueAt(vm_, arrayObject, index);
1801     char getBuffer[20];
1802     resultString->WriteUtf8(vm_, getBuffer, inputString.length());
1803     std::string getResult(getBuffer);
1804     GTEST_LOG_(INFO) << "sample_getStringValue_index_0: " << getResult;
1805     bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, stringValue);
1806     GTEST_LOG_(INFO) << "sample_setStringValue_index_5"
1807                      << " setResult: " << setResult;
1808     std::string changedString = "Change Test";
1809     Local<StringRef> changedStringValue = StringRef::NewFromUtf8(vm_, changedString.c_str());
1810     ArrayRef::SetValueAt(vm_, arrayObject, index, changedStringValue);
1811     Local<StringRef> resultChangedString = ArrayRef::GetValueAt(vm_, arrayObject, index);
1812     char changedBuffer[20];
1813     resultChangedString->WriteUtf8(vm_, changedBuffer, changedString.length());
1814     std::string changedResult(changedBuffer);
1815     GTEST_LOG_(INFO) << "sample_getChangedStringValue_index_0: " << changedResult;
1816     for (int i = 0; i < (int)arrayLength; i++) {
1817         Local<StringRef> printString = ArrayRef::GetValueAt(vm_, arrayObject, i);
1818         char printBuffer[20];
1819         printString->WriteUtf8(vm_, printBuffer, inputString.length());
1820         std::string printResult(printBuffer);
1821         GTEST_LOG_(INFO) << "sample_printStringValue_index_" << i << ": " << printResult;
1822         memset_s(printBuffer, sizeof(printBuffer), 0, sizeof(printBuffer));
1823     }
1824 }
1825 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Int8Array)1826 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Int8Array)
1827 {
1828     LocalScope scope(vm_);
1829     const int32_t length = 15; // arraybuffer length = 15
1830     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1831     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1832     int8_t *ptr = (int8_t *)arrayBuffer->GetBuffer(vm_);
1833     for (int i = 0; i < arrayLength; i++) {
1834         *ptr = int8_t(i + 10);
1835         ptr++;
1836     }
1837     int32_t byteOffset = 5;      // byte offset = 5
1838     int32_t int8ArrayLength = 6; // array length = 6
1839     Local<Int8ArrayRef> typedArray = Int8ArrayRef::New(vm_, arrayBuffer, byteOffset, int8ArrayLength);
1840     GTEST_LOG_(INFO) << "sample_Int8Array_byteLength : " << typedArray->ByteLength(vm_);
1841     GTEST_LOG_(INFO) << "sample_Int8Array_byteOffset : " << typedArray->ByteOffset(vm_);
1842     GTEST_LOG_(INFO) << "sample_Int8Array_arrayLength : " << typedArray->ArrayLength(vm_);
1843     int8_t *result = (int8_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1844     for (int i = 0; i < int8ArrayLength; i++) {
1845         int value = int8_t(*result);
1846         GTEST_LOG_(INFO) << "sample_Int8Array_getInt8ArrayValue : " << value;
1847         result++;
1848     }
1849 }
1850 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Uint8Array)1851 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint8Array)
1852 {
1853     LocalScope scope(vm_);
1854     const int32_t length = 15; // arraybuffer length = 15
1855     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1856     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1857     uint8_t *ptr = (uint8_t *)arrayBuffer->GetBuffer(vm_);
1858     for (int i = 0; i < arrayLength; i++) {
1859         *ptr = uint8_t(i + 10);
1860         ptr++;
1861     }
1862     int32_t byteOffset = 5;       // byte offset = 5
1863     int32_t Uint8ArrayLength = 6; // array length = 6
1864     Local<Uint8ArrayRef> typedArray = Uint8ArrayRef::New(vm_, arrayBuffer, byteOffset, Uint8ArrayLength);
1865     GTEST_LOG_(INFO) << "sample_Uint8Array_byteLength : " << typedArray->ByteLength(vm_);
1866     GTEST_LOG_(INFO) << "sample_Uint8Array_byteOffset : " << typedArray->ByteOffset(vm_);
1867     GTEST_LOG_(INFO) << "sample_Uint8Array_arrayLength : " << typedArray->ArrayLength(vm_);
1868     uint8_t *result = (uint8_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1869     for (int i = 0; i < Uint8ArrayLength; i++) {
1870         int value = uint8_t(*result);
1871         GTEST_LOG_(INFO) << "sample_Uint8Array_getUint8ArrayValue : " << value;
1872         result++;
1873     }
1874 }
1875 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Uint8ClampedArray)1876 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint8ClampedArray)
1877 {
1878     LocalScope scope(vm_);
1879     const int32_t length = 15; // arraybuffer length = 15
1880     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1881     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1882     uint8_t *ptr = (uint8_t *)arrayBuffer->GetBuffer(vm_);
1883     for (int i = 0; i < arrayLength; i++) {
1884         *ptr = uint8_t(i + 10);
1885         ptr++;
1886     }
1887     int32_t byteOffset = 5;     // byte offset = 5
1888     int32_t uint8ArrLength = 6; // array length = 6
1889     Local<Uint8ClampedArrayRef> typedArray = Uint8ClampedArrayRef::New(vm_, arrayBuffer, byteOffset, uint8ArrLength);
1890     GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_byteLength : " << typedArray->ByteLength(vm_);
1891     GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_byteOffset : " << typedArray->ByteOffset(vm_);
1892     GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_arrayLength : " << typedArray->ArrayLength(vm_);
1893     uint8_t *result = (uint8_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1894     for (int i = 0; i < uint8ArrLength; i++) {
1895         int value = uint8_t(*result);
1896         GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_getUint8ClampedArrayValue : " << value;
1897         result++;
1898     }
1899 }
1900 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Int16Array)1901 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Int16Array)
1902 {
1903     LocalScope scope(vm_);
1904     const int32_t length = 30; // arraybuffer length = 30
1905     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1906     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1907     int16_t *ptr = (int16_t *)arrayBuffer->GetBuffer(vm_);
1908     for (int i = 0; i < arrayLength / 2; i++) {
1909         *ptr = int16_t(i + 10);
1910         ptr++;
1911     }
1912     int32_t byteOffset = 4;       // byte offset = 4
1913     int32_t int16ArrayLength = 6; // array length = 6
1914     Local<Int16ArrayRef> typedArray = Int16ArrayRef::New(vm_, arrayBuffer, byteOffset, int16ArrayLength);
1915     GTEST_LOG_(INFO) << "sample_Int16Array_byteLength : " << typedArray->ByteLength(vm_);
1916     GTEST_LOG_(INFO) << "sample_Int16Array_byteOffset : " << typedArray->ByteOffset(vm_);
1917     GTEST_LOG_(INFO) << "sample_Int16Array_arrayLength : " << typedArray->ArrayLength(vm_);
1918     int16_t *result = (int16_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1919     for (int i = 0; i < int16ArrayLength; i++) {
1920         int value = int16_t(*result);
1921         GTEST_LOG_(INFO) << "sample_Int16Array_getInt16ArrayValue : " << value;
1922         result++;
1923     }
1924 }
1925 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Uint16Array)1926 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint16Array)
1927 {
1928     LocalScope scope(vm_);
1929     const int32_t length = 30; // arraybuffer length = 30
1930     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1931     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1932     uint16_t *ptr = (uint16_t *)arrayBuffer->GetBuffer(vm_);
1933     for (int i = 0; i < arrayLength / 2; i++) {
1934         *ptr = uint16_t(i + 10);
1935         ptr++;
1936     }
1937     int32_t byteOffset = 4;        // byte offset = 4
1938     int32_t uint16ArrayLength = 6; // array length = 6
1939     Local<Uint16ArrayRef> typedArray = Uint16ArrayRef::New(vm_, arrayBuffer, byteOffset, uint16ArrayLength);
1940     GTEST_LOG_(INFO) << "sample_Uint16Array_byteLength : " << typedArray->ByteLength(vm_);
1941     GTEST_LOG_(INFO) << "sample_Uint16Array_byteOffset : " << typedArray->ByteOffset(vm_);
1942     GTEST_LOG_(INFO) << "sample_Uint16Array_arrayLength : " << typedArray->ArrayLength(vm_);
1943     uint16_t *result = (uint16_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1944     for (int i = 0; i < uint16ArrayLength; i++) {
1945         int value = uint16_t(*result);
1946         GTEST_LOG_(INFO) << "sample_Uint16Array_getUint16ArrayValue : " << value;
1947         result++;
1948     }
1949 }
1950 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Int32Array)1951 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Int32Array)
1952 {
1953     LocalScope scope(vm_);
1954     const int32_t length = 32; // arraybuffer length = 32
1955     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1956     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1957     int32_t *ptr = (int32_t *)arrayBuffer->GetBuffer(vm_);
1958     for (int i = 0; i < arrayLength / 4; i++) {
1959         *ptr = int32_t(i + 10);
1960         ptr++;
1961     }
1962     int32_t byteOffset = 4;       // byte offset = 4
1963     int32_t int32ArrayLength = 6; // array length = 6
1964     Local<Int32ArrayRef> typedArray = Int32ArrayRef::New(vm_, arrayBuffer, byteOffset, int32ArrayLength);
1965     GTEST_LOG_(INFO) << "sample_Int32Array_byteLength : " << typedArray->ByteLength(vm_);
1966     GTEST_LOG_(INFO) << "sample_Int32Array_byteOffset : " << typedArray->ByteOffset(vm_);
1967     GTEST_LOG_(INFO) << "sample_Int32Array_arrayLength : " << typedArray->ArrayLength(vm_);
1968     int32_t *result = (int32_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1969     for (int i = 0; i < int32ArrayLength; i++) {
1970         int value = int32_t(*result);
1971         GTEST_LOG_(INFO) << "sample_Int32Array_getInt32ArrayValue : " << value;
1972         result++;
1973     }
1974 }
1975 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Uint32Array)1976 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint32Array)
1977 {
1978     LocalScope scope(vm_);
1979     const int32_t length = 32; // arraybuffer length = 32
1980     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
1981     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
1982     uint32_t *ptr = (uint32_t *)arrayBuffer->GetBuffer(vm_);
1983     for (int i = 0; i < arrayLength / 4; i++) {
1984         *ptr = uint32_t(i + 10);
1985         ptr++;
1986     }
1987     int32_t byteOffset = 4;        // byte offset = 4
1988     int32_t uint32ArrayLength = 6; // array length = 6
1989     Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm_, arrayBuffer, byteOffset, uint32ArrayLength);
1990     GTEST_LOG_(INFO) << "sample_Uint32Array_byteLength : " << typedArray->ByteLength(vm_);
1991     GTEST_LOG_(INFO) << "sample_Uint32Array_byteOffset : " << typedArray->ByteOffset(vm_);
1992     GTEST_LOG_(INFO) << "sample_Uint32Array_arrayLength : " << typedArray->ArrayLength(vm_);
1993     uint32_t *result = (uint32_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
1994     for (int i = 0; i < uint32ArrayLength; i++) {
1995         int value = uint32_t(*result);
1996         GTEST_LOG_(INFO) << "sample_Uint32Array_getUint32ArrayValue : " << value;
1997         result++;
1998     }
1999 }
2000 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Float32Array)2001 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Float32Array)
2002 {
2003     LocalScope scope(vm_);
2004     const int32_t length = 32; // arraybuffer length = 32
2005     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
2006     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
2007     float *ptr = (float *)arrayBuffer->GetBuffer(vm_);
2008     for (int i = 0; i < arrayLength / 4; i++) {
2009         *ptr = float(i + 10);
2010         ptr++;
2011     }
2012     int32_t byteOffset = 4;         // byte offset = 4
2013     int32_t float32ArrayLength = 6; // array length = 6
2014     Local<Float32ArrayRef> typedArray = Float32ArrayRef::New(vm_, arrayBuffer, byteOffset, float32ArrayLength);
2015     GTEST_LOG_(INFO) << "sample_Float32Array_byteLength : " << typedArray->ByteLength(vm_);
2016     GTEST_LOG_(INFO) << "sample_Float32Array_byteOffset : " << typedArray->ByteOffset(vm_);
2017     GTEST_LOG_(INFO) << "sample_Float32Array_arrayLength : " << typedArray->ArrayLength(vm_);
2018     float *result = (float *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
2019     for (int i = 0; i < float32ArrayLength; i++) {
2020         int value = float(*result);
2021         GTEST_LOG_(INFO) << "sample_Float32Array_getFloat32ArrayValue : " << value;
2022         result++;
2023     }
2024 }
2025 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_Float64Array)2026 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Float64Array)
2027 {
2028     LocalScope scope(vm_);
2029     const int32_t length = 64; // arraybuffer length = 64
2030     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
2031     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
2032     double *ptr = (double *)arrayBuffer->GetBuffer(vm_);
2033     for (int i = 0; i < arrayLength / 8; i++) {
2034         *ptr = double(i + 10);
2035         ptr++;
2036     }
2037     int32_t byteOffset = 8;         // byte offset = 8
2038     int32_t float64ArrayLength = 6; // array length = 6
2039     Local<Float64ArrayRef> typedArray = Float64ArrayRef::New(vm_, arrayBuffer, byteOffset, float64ArrayLength);
2040     GTEST_LOG_(INFO) << "sample_Float64Array_byteLength : " << typedArray->ByteLength(vm_);
2041     GTEST_LOG_(INFO) << "sample_Float64Array_byteOffset : " << typedArray->ByteOffset(vm_);
2042     GTEST_LOG_(INFO) << "sample_Float64Array_arrayLength : " << typedArray->ArrayLength(vm_);
2043     double *result = (double *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
2044     for (int i = 0; i < float64ArrayLength; i++) {
2045         int value = double(*result);
2046         GTEST_LOG_(INFO) << "sample_Float64Array_getFloat64ArrayValue : " << value;
2047         result++;
2048     }
2049 }
2050 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_BigInt64Array)2051 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_BigInt64Array)
2052 {
2053     LocalScope scope(vm_);
2054     const int32_t length = 64; // arraybuffer length = 64
2055     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
2056     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
2057     int64_t *ptr = (int64_t *)arrayBuffer->GetBuffer(vm_);
2058     for (int i = 0; i < arrayLength / 8; i++) {
2059         *ptr = int64_t(i * 100);
2060         ptr++;
2061     }
2062     int32_t byteOffset = 8;          // byte offset = 8
2063     int32_t bigInt64ArrayLength = 6; // array length = 6
2064     Local<BigInt64ArrayRef> typedArray = BigInt64ArrayRef::New(vm_, arrayBuffer, byteOffset, bigInt64ArrayLength);
2065     GTEST_LOG_(INFO) << "sample_BigInt64Array_byteLength : " << typedArray->ByteLength(vm_);
2066     GTEST_LOG_(INFO) << "sample_BigInt64Array_byteOffset : " << typedArray->ByteOffset(vm_);
2067     GTEST_LOG_(INFO) << "sample_BigInt64Array_arrayLength : " << typedArray->ArrayLength(vm_);
2068     int64_t *result = (int64_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
2069     for (int i = 0; i < bigInt64ArrayLength; i++) {
2070         int value = int64_t(*result);
2071         GTEST_LOG_(INFO) << "sample_BigInt64Array_getBigInt64ArrayValue : " << value;
2072         result++;
2073     }
2074 }
2075 
HWTEST_F_L0(JSNApiSampleTest,sample_TypedArrayRef_BigUint64Array)2076 HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_BigUint64Array)
2077 {
2078     LocalScope scope(vm_);
2079     const int32_t length = 64; // arraybuffer length = 64
2080     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
2081     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
2082     uint64_t *ptr = (uint64_t *)arrayBuffer->GetBuffer(vm_);
2083     for (int i = 0; i < arrayLength / 8; i++) {
2084         *ptr = int64_t(i * 100);
2085         ptr++;
2086     }
2087     int32_t byteOffset = 8;           // byte offset = 8
2088     int32_t bigUint64ArrayLength = 6; // array length = 6
2089     Local<BigUint64ArrayRef> typedArray = BigUint64ArrayRef::New(vm_, arrayBuffer, byteOffset, bigUint64ArrayLength);
2090     GTEST_LOG_(INFO) << "sample_BigUint64Array_byteLength : " << typedArray->ByteLength(vm_);
2091     GTEST_LOG_(INFO) << "sample_BigUint64Array_byteOffset : " << typedArray->ByteOffset(vm_);
2092     GTEST_LOG_(INFO) << "sample_BigUint64Array_arrayLength : " << typedArray->ArrayLength(vm_);
2093     uint64_t *result = (uint64_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_);
2094     for (int i = 0; i < bigUint64ArrayLength; i++) {
2095         int value = uint64_t(*result);
2096         GTEST_LOG_(INFO) << "sample_BigUint64Array_getBigUint64ArrayValue : " << value;
2097         result++;
2098     }
2099 }
2100 
HWTEST_F_L0(JSNApiSampleTest,sample_DataViewRef)2101 HWTEST_F_L0(JSNApiSampleTest, sample_DataViewRef)
2102 {
2103     LocalScope scope(vm_);
2104     const int32_t length = 15; // arraybuffer length = 15
2105     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
2106     int32_t byteOffset = 5;     // byte offset = 5
2107     int32_t dataViewLength = 7; // dataview length = 7
2108     Local<DataViewRef> dataView = DataViewRef::New(vm_, arrayBuffer, byteOffset, dataViewLength);
2109     GTEST_LOG_(INFO) << "sample_DataView_byteLength : " << dataView->ByteLength();
2110     GTEST_LOG_(INFO) << "sample_DataView_byteOffset : " << dataView->ByteOffset();
2111     GTEST_LOG_(INFO) << "sample_DataView_getArrayBuffer : " << dataView->GetArrayBuffer(vm_)->GetBuffer(vm_);
2112 }
2113 
HWTEST_F_L0(JSNApiSampleTest,sample_ArrayBuffer_New_Detach)2114 HWTEST_F_L0(JSNApiSampleTest, sample_ArrayBuffer_New_Detach)
2115 {
2116     LocalScope scope(vm_);
2117     const int32_t length = 32; // arraybuffer length = 32
2118     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
2119     int32_t arrayLength = arrayBuffer->ByteLength(vm_);
2120     GTEST_LOG_(INFO) << "sample_ArrayBuffer_byteLength : " << arrayLength;
2121     GTEST_LOG_(INFO) << "sample_ArrayBuffer_getArrayBuffer : " << arrayBuffer->GetBuffer(vm_);
2122     arrayBuffer->Detach(vm_);
2123     GTEST_LOG_(INFO) << "sample_ArrayBuffer_getDetachArrayBuffer : " << arrayBuffer->GetBuffer(vm_);
2124     bool result = arrayBuffer->IsDetach(vm_);
2125     GTEST_LOG_(INFO) << "sample_ArrayBuffer_getIsDetach : " << result;
2126 }
2127 
HWTEST_F_L0(JSNApiSampleTest,sample_ArrayBufferWithBuffer_New_Detach)2128 HWTEST_F_L0(JSNApiSampleTest, sample_ArrayBufferWithBuffer_New_Detach)
2129 {
2130     static bool isFree = false;
2131     struct Data {
2132         int32_t length;
2133     };
2134     const int32_t length = 5; // arraybuffer length = 5
2135     Data *data = new Data();
2136     data->length = length;
2137     NativePointerCallback deleter = [](void *env, void *buffer, void *data) -> void {
2138         delete[] reinterpret_cast<uint8_t *>(buffer);
2139         Data *currentData = reinterpret_cast<Data *>(data);
2140         delete currentData;
2141         isFree = true;
2142     };
2143     LocalScope scope(vm_);
2144     uint8_t *buffer = new uint8_t[length]();
2145     Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data);
2146     GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_byteLength : " << arrayBuffer->ByteLength(vm_);
2147     GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_getArrayBuffer : " << arrayBuffer->GetBuffer(vm_);
2148     arrayBuffer->Detach(vm_);
2149     GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_getDetachArrayBuffer : " << arrayBuffer->GetBuffer(vm_);
2150     bool result = arrayBuffer->IsDetach(vm_);
2151     GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_getIsDetach : " << result;
2152 }
2153 
HWTEST_F_L0(JSNApiSampleTest,sample_Buffer_New_GetBuffer)2154 HWTEST_F_L0(JSNApiSampleTest, sample_Buffer_New_GetBuffer)
2155 {
2156     LocalScope scope(vm_);
2157     const int32_t length = 5; // buffer length = 5
2158     Local<BufferRef> buffer = BufferRef::New(vm_, length);
2159     GTEST_LOG_(INFO) << "sample_Buffer_byteLength : " << buffer->ByteLength(vm_);
2160     GTEST_LOG_(INFO) << "sample_Buffer_getBuffer : " << buffer->GetBuffer(vm_);
2161 }
2162 
HWTEST_F_L0(JSNApiSampleTest,sample_BufferWithBuffer_New_GetBuffer)2163 HWTEST_F_L0(JSNApiSampleTest, sample_BufferWithBuffer_New_GetBuffer)
2164 {
2165     static bool isFree = false;
2166     struct Data {
2167         int32_t length;
2168     };
2169     const int32_t length = 5; // buffer length = 5
2170     Data *data = new Data();
2171     data->length = length;
2172     NativePointerCallback deleter = [](void *env, void *buffer, void *data) -> void {
2173         delete[] reinterpret_cast<uint8_t *>(buffer);
2174         Data *currentData = reinterpret_cast<Data *>(data);
2175         delete currentData;
2176         isFree = true;
2177     };
2178     LocalScope scope(vm_);
2179     uint8_t *buffer = new uint8_t[length]();
2180     Local<BufferRef> bufferObj = BufferRef::New(vm_, buffer, length, deleter, data);
2181     GTEST_LOG_(INFO) << "sample_bufferWithBuffer_byteLength : " << bufferObj->ByteLength(vm_);
2182     GTEST_LOG_(INFO) << "sample_bufferWithBuffer_getBuffer : " << bufferObj->GetBuffer(vm_);
2183 }
2184 
2185 /* domo8 异步操作。 ts:
2186  * new Promise(function (resolve, reject) {
2187  * var a = 0;
2188  * var b = 1;
2189  * if (b == 0) reject("Divide zero");
2190  * else resolve(a / b);
2191  * }).then(function (value) {
2192  * console.log("a / b = " + value);
2193  * }).catch(function (err) {
2194  * console.log(err);
2195  * }).finally(function () {
2196  * console.log("End");
2197  * });
2198  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo8_async_test_1)2199 HWTEST_F_L0(JSNApiSampleTest, sample_demo8_async_test_1)
2200 {
2201     GTEST_LOG_(INFO) << "sample_demo8_async_test_1 =======================================";
2202     LocalScope scope(vm_);
2203 
2204     Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
2205     capability->GetPromise(vm_)
2206         ->Then(vm_, FunctionRef::New(vm_,
2207         // 函数体
2208         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
2209             EcmaVM *vm = runtimeInfo->GetVM();
2210             LocalScope scope(vm);
2211             Local<JSValueRef> jsNum = runtimeInfo->GetCallArgRef(0);
2212             int num = jsNum->Int32Value(vm);
2213             // ts: console.log("a / b = " + value);
2214             GTEST_LOG_(INFO) << "a / b = " << num;
2215             return JSValueRef::Undefined(vm);
2216         }))
2217         ->Catch(vm_, FunctionRef::New(vm_,
2218         // 函数体
2219         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
2220             EcmaVM *vm = runtimeInfo->GetVM();
2221             LocalScope scope(vm);
2222             Local<JSValueRef> jsStr = runtimeInfo->GetCallArgRef(0);
2223             std::string err = jsStr->ToString(vm)->ToString(vm);
2224             // ts: console.log(err);
2225             GTEST_LOG_(INFO) << err;
2226             return JSValueRef::Undefined(vm);
2227         }))
2228         ->Finally(vm_, FunctionRef::New(vm_,
2229         // 函数体
2230         [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
2231             EcmaVM *vm = runtimeInfo->GetVM();
2232             LocalScope scope(vm);
2233             // ts: console.log("End");
2234             GTEST_LOG_(INFO) << "End";
2235             return JSValueRef::Undefined(vm);
2236         }));
2237 
2238     int a = 0;
2239     int b = 0;
2240     if (b == 0) {
2241         capability->Reject(vm_, StringRef::NewFromUtf8(vm_, "Divide zero"));
2242     } else {
2243         capability->Resolve(vm_, NumberRef::New(vm_, int(a / b)));
2244     }
2245 
2246     GTEST_LOG_(INFO) << "sample_demo8_async_test_1 =======================================";
2247 }
2248 
2249 // JSValueRef转为字符串输出。
jsValue2String(EcmaVM * vm,Local<JSValueRef> & jsVal)2250 std::string jsValue2String(EcmaVM *vm, Local<JSValueRef> &jsVal)
2251 {
2252     if (jsVal->IsString(vm)) {
2253         return "type string, val : " + jsVal->ToString(vm)->ToString(vm);
2254     } else if (jsVal->IsNumber()) {
2255         return "type number, val : " + std::to_string(jsVal->Int32Value(vm));
2256     } else if (jsVal->IsBoolean()) {
2257         return "type bool, val : " + std::to_string(jsVal->BooleaValue(vm));
2258     } else if (jsVal->IsSymbol(vm)) {
2259         Local<SymbolRef> symbol = jsVal;
2260         return "type symbol, val : " + symbol->GetDescription(vm)->ToString(vm);
2261     } else {
2262         return "type other : " + jsVal->ToString(vm)->ToString(vm);
2263     }
2264 }
2265 
MapSetValue(EcmaVM * vm,Local<MapRef> & map,Local<JSValueRef> symbolKey)2266 void MapSetValue(EcmaVM *vm, Local<MapRef> &map, Local<JSValueRef> symbolKey)
2267 {
2268     map->Set(vm, StringRef::NewFromUtf8(vm, "key1"), StringRef::NewFromUtf8(vm, "val1"));
2269     int num2 = 222; // random number
2270     map->Set(vm, StringRef::NewFromUtf8(vm, "key2"), NumberRef::New(vm, num2));
2271     map->Set(vm, StringRef::NewFromUtf8(vm, "key3"), BooleanRef::New(vm, true));
2272     map->Set(vm, StringRef::NewFromUtf8(vm, "key4"), SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "val4")));
2273     int num5 = 55; // random number
2274     map->Set(vm, IntegerRef::New(vm, num5), StringRef::NewFromUtf8(vm, "val5"));
2275     int num61 = 66;  // random number
2276     int num62 = 666; // random number
2277     map->Set(vm, IntegerRef::New(vm, num61), IntegerRef::New(vm, num62));
2278     map->Set(vm, BooleanRef::New(vm, true), StringRef::NewFromUtf8(vm, "val7"));
2279     map->Set(vm, symbolKey, StringRef::NewFromUtf8(vm, "val8"));
2280 }
2281 
MapGetValue(EcmaVM * vm,Local<MapRef> & map,Local<JSValueRef> symbolKey)2282 void MapGetValue(EcmaVM *vm, Local<MapRef> &map, Local<JSValueRef> symbolKey)
2283 {
2284     Local<JSValueRef> val1 = map->Get(vm, StringRef::NewFromUtf8(vm, "key1"));
2285     bool val1IsString = val1->IsString(vm);
2286     GTEST_LOG_(INFO) << "key1 : IsString:" << val1IsString << "    val:" << val1->ToString(vm)->ToString(vm);
2287 
2288     Local<JSValueRef> val2 = map->Get(vm, StringRef::NewFromUtf8(vm, "key2"));
2289     bool val2IsNumber = val2->IsNumber();
2290     GTEST_LOG_(INFO) << "key2 : IsNumber:" << val2IsNumber << "    val:" << val2->Int32Value(vm);
2291 
2292     Local<JSValueRef> val3 = map->Get(vm, StringRef::NewFromUtf8(vm, "key3"));
2293     bool val3IsBoolean = val3->IsBoolean();
2294     GTEST_LOG_(INFO) << "key3 : IsBoolean:" << val3IsBoolean << "    val:" << val3->BooleaValue(vm);
2295 
2296     Local<JSValueRef> val4 = map->Get(vm, StringRef::NewFromUtf8(vm, "key4"));
2297     bool val4IsSymbol = val4->IsSymbol(vm);
2298     Local<SymbolRef> val4Symbol = val4;
2299     GTEST_LOG_(INFO) << "key4 : IsSymbol:" << val4IsSymbol << "    val:"
2300                      << val4Symbol->GetDescription(vm)->ToString(vm);
2301 
2302     int num5 = 55; // random number
2303     Local<JSValueRef> val5 = map->Get(vm, IntegerRef::New(vm, num5));
2304     GTEST_LOG_(INFO) << "55 : " << val5->ToString(vm)->ToString(vm);
2305 
2306     int num6 = 66; // random number
2307     Local<JSValueRef> val6 = map->Get(vm, IntegerRef::New(vm, num6));
2308     GTEST_LOG_(INFO) << "66 : " << val6->Int32Value(vm);
2309     Local<JSValueRef> val7 = map->Get(vm, BooleanRef::New(vm, true));
2310     GTEST_LOG_(INFO) << "true : " << val7->ToString(vm)->ToString(vm);
2311 
2312     Local<JSValueRef> val8 = map->Get(vm, symbolKey);
2313     GTEST_LOG_(INFO) << "SymbolRef(key8)  : " << val8->ToString(vm)->ToString(vm);
2314 
2315     Local<JSValueRef> val82 = map->Get(vm, SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "key8")));
2316     GTEST_LOG_(INFO) << "new SymbolRef(key8) is Undefined : " << val82->IsUndefined();
2317 
2318     int32_t size = map->GetSize(vm);
2319     GTEST_LOG_(INFO) << "size : " << size;
2320     int32_t totalElement = map->GetTotalElements(vm);
2321     GTEST_LOG_(INFO) << "total element : " << totalElement;
2322 
2323     for (int i = 0; i < size; ++i) {
2324         Local<JSValueRef> jsKey = map->GetKey(vm, i);
2325         Local<JSValueRef> jsVal = map->GetValue(vm, i);
2326         GTEST_LOG_(INFO) << "for map index : " << i << "    key : " << jsValue2String(vm, jsKey) << "    val : " <<
2327             jsValue2String(vm, jsVal);
2328     }
2329 }
2330 
MapIteratorGetValue(EcmaVM * vm,Local<MapRef> & map)2331 void MapIteratorGetValue(EcmaVM *vm, Local<MapRef> &map)
2332 {
2333     Local<MapIteratorRef> mapIter = MapIteratorRef::New(vm, map);
2334     ecmascript::EcmaRuntimeCallInfo *mapIterInfo = mapIter->GetEcmaRuntimeCallInfo(vm);
2335 
2336     Local<StringRef> kind = mapIter->GetKind(vm);
2337     GTEST_LOG_(INFO) << "Map Iterator kind : " << kind->ToString(vm);
2338 
2339     for (Local<ArrayRef> array = MapIteratorRef::Next(vm, mapIterInfo); array->IsArray(vm);
2340         array = MapIteratorRef::Next(vm, mapIterInfo)) {
2341         int index = mapIter->GetIndex() - 1;
2342         Local<JSValueRef> jsKey = ArrayRef::GetValueAt(vm, array, 0);
2343         Local<JSValueRef> jsVal = ArrayRef::GetValueAt(vm, array, 1);
2344         GTEST_LOG_(INFO) << "for map iterator index : " << index << "    key : " << jsValue2String(vm, jsKey) <<
2345             "    val : " << jsValue2String(vm, jsVal);
2346     }
2347 }
2348 
2349 /* demo9 Map,MapIterator 的操作。 */
HWTEST_F_L0(JSNApiSampleTest,sample_demo9_map_test_1_MapRef_MapIteratorRef)2350 HWTEST_F_L0(JSNApiSampleTest, sample_demo9_map_test_1_MapRef_MapIteratorRef)
2351 {
2352     GTEST_LOG_(INFO) << "sample_demo9_map_test_1_MapRef_MapIteratorRef =======================================";
2353     LocalScope scope(vm_);
2354 
2355     Local<MapRef> map = MapRef::New(vm_);
2356     Local<JSValueRef> symbolKey = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "key8"));
2357     MapSetValue(vm_, map, symbolKey);
2358     MapGetValue(vm_, map, symbolKey);
2359     MapIteratorGetValue(vm_, map);
2360     GTEST_LOG_(INFO) << "sample_demo9_map_test_1_MapRef_MapIteratorRef =======================================";
2361 }
2362 
2363 /* demo9 WeakMap 的操作。 */
HWTEST_F_L0(JSNApiSampleTest,sample_demo9_map_test_2_WeakMapref)2364 HWTEST_F_L0(JSNApiSampleTest, sample_demo9_map_test_2_WeakMapref)
2365 {
2366     GTEST_LOG_(INFO) << "sample_demo9_map_test_2_WeakMapref =======================================";
2367     LocalScope scope(vm_);
2368 
2369     Local<WeakMapRef> weakMap = WeakMapRef::New(vm_);
2370     weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val1"));
2371     int num2 = 222; // random number
2372     weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), NumberRef::New(vm_, num2));
2373     weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key3"), BooleanRef::New(vm_, true));
2374     weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key4"), SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "val4")));
2375     weakMap->Set(vm_, IntegerRef::New(vm_, 55), StringRef::NewFromUtf8(vm_, "val5"));
2376     int num6 = 666; // random number
2377     weakMap->Set(vm_, IntegerRef::New(vm_, 66), IntegerRef::New(vm_, num6));
2378     weakMap->Set(vm_, BooleanRef::New(vm_, true), StringRef::NewFromUtf8(vm_, "val7"));
2379     Local<JSValueRef> key8 = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "key8"));
2380     weakMap->Set(vm_, key8, StringRef::NewFromUtf8(vm_, "val8"));
2381 
2382     int size = weakMap->GetSize(vm_);
2383     GTEST_LOG_(INFO) << "size : " << size;
2384     int32_t totalElements = weakMap->GetTotalElements(vm_);
2385     GTEST_LOG_(INFO) << "total elements : " << totalElements;
2386 
2387     for (int i = 0; i < size; ++i) {
2388         Local<JSValueRef> jsKey = weakMap->GetKey(vm_, i);
2389         Local<JSValueRef> jsVal = weakMap->GetValue(vm_, i);
2390         GTEST_LOG_(INFO) << "for WeakMap index : " << i << "    key : " << jsValue2String(vm_, jsKey) << "    val : " <<
2391             jsValue2String(vm_, jsVal);
2392     }
2393 
2394     bool hasKey2 = weakMap->Has(vm_, StringRef::NewFromUtf8(vm_, "key2"));
2395     GTEST_LOG_(INFO) << "Has Key2 : " << hasKey2;
2396     bool hasKey222 = weakMap->Has(vm_, StringRef::NewFromUtf8(vm_, "key222"));
2397     GTEST_LOG_(INFO) << "Has key222 : " << hasKey222;
2398 
2399     GTEST_LOG_(INFO) << "sample_demo9_map_test_2_WeakMapref =======================================";
2400 }
2401 
2402 /* demo10 set 的使用 */
HWTEST_F_L0(JSNApiSampleTest,sample_demo10_set)2403 HWTEST_F_L0(JSNApiSampleTest, sample_demo10_set)
2404 {
2405     GTEST_LOG_(INFO) << "sample_demo10_set =======================================";
2406     LocalScope scope(vm_);
2407     Local<SetRef> set = SetRef::New(vm_);
2408 
2409     set->Add(vm_, StringRef::NewFromUtf8(vm_, "val1"));
2410     int num2 = 222; // random number
2411     set->Add(vm_, NumberRef::New(vm_, num2));
2412     set->Add(vm_, BooleanRef::New(vm_, true));
2413     set->Add(vm_, SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "val4")));
2414     set->Add(vm_, StringRef::NewFromUtf8(vm_, "val5"));
2415     int num6 = 666; // random number
2416     set->Add(vm_, IntegerRef::New(vm_, num6));
2417 
2418     int32_t size = set->GetSize(vm_);
2419     GTEST_LOG_(INFO) << "size : " << size;
2420     int32_t totalElement = set->GetTotalElements(vm_);
2421     GTEST_LOG_(INFO) << "total element : " << totalElement;
2422 
2423     for (int i = 0; i < size; ++i) {
2424         Local<JSValueRef> jsVal = set->GetValue(vm_, i);
2425         GTEST_LOG_(INFO) << "for set index : " << i << "    val : " << jsValue2String(vm_, jsVal);
2426     }
2427 
2428     // Iterator
2429     Local<SetIteratorRef> setIter = SetIteratorRef::New(vm_, set);
2430     ecmascript::EcmaRuntimeCallInfo *info = setIter->GetEcmaRuntimeCallInfo(vm_);
2431 
2432     Local<StringRef> kind = setIter->GetKind(vm_);
2433     GTEST_LOG_(INFO) << "Set Iterator kind : " << kind->ToString(vm_);
2434 
2435     for (Local<ArrayRef> array = SetIteratorRef::Next(vm_, info); array->IsArray(vm_);
2436         array = SetIteratorRef::Next(vm_, info)) {
2437         int index = setIter->GetIndex() - 1;
2438         Local<JSValueRef> jsVal = ArrayRef::GetValueAt(vm_, array, 1);
2439         GTEST_LOG_(INFO) << "for set iterator index : " << index << "    val : " << jsValue2String(vm_, jsVal);
2440     }
2441     GTEST_LOG_(INFO) << "sample_demo10_set =======================================";
2442 }
2443 
2444 /* demo10 WeakSet 的使用 */
HWTEST_F_L0(JSNApiSampleTest,sample_demo10_weakset)2445 HWTEST_F_L0(JSNApiSampleTest, sample_demo10_weakset)
2446 {
2447     GTEST_LOG_(INFO) << "sample_demo10_weakset =======================================";
2448     LocalScope scope(vm_);
2449     Local<WeakSetRef> weakSet = WeakSetRef::New(vm_);
2450 
2451     weakSet->Add(vm_, StringRef::NewFromUtf8(vm_, "val1"));
2452     int num2 = 666; // random number
2453     weakSet->Add(vm_, NumberRef::New(vm_, num2));
2454     weakSet->Add(vm_, BooleanRef::New(vm_, true));
2455     weakSet->Add(vm_, SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "val4")));
2456     weakSet->Add(vm_, StringRef::NewFromUtf8(vm_, "val5"));
2457     int num6 = 666; // random number
2458     weakSet->Add(vm_, IntegerRef::New(vm_, num6));
2459 
2460     int32_t size = weakSet->GetSize(vm_);
2461     GTEST_LOG_(INFO) << "size : " << size;
2462     int32_t totalElement = weakSet->GetTotalElements(vm_);
2463     GTEST_LOG_(INFO) << "total element : " << totalElement;
2464 
2465     for (int i = 0; i < size; ++i) {
2466         Local<JSValueRef> jsVal = weakSet->GetValue(vm_, i);
2467         GTEST_LOG_(INFO) << "for weakset index : " << i << "    val : " << jsValue2String(vm_, jsVal);
2468     }
2469     GTEST_LOG_(INFO) << "sample_demo10_weakset =======================================";
2470 }
2471 
2472 // json对象获取值。
JsonObjGetValue(EcmaVM * vm,Local<ObjectRef> obj)2473 void JsonObjGetValue(EcmaVM *vm, Local<ObjectRef> obj)
2474 {
2475     Local<JSValueRef> jsVal1 = obj->Get(vm, StringRef::NewFromUtf8(vm, "str1"));
2476     bool jsVal1IsString = jsVal1->IsString(vm);
2477     Local<StringRef> val1 = jsVal1->ToString(vm);
2478     GTEST_LOG_(INFO) << "str1 : is string : " << jsVal1IsString << "  value : " << val1->ToString(vm);
2479     Local<JSValueRef> jsVal2 = obj->Get(vm, StringRef::NewFromUtf8(vm, "str2"));
2480     bool jsVal2IsNumber = jsVal2->IsNumber();
2481     int val2 = jsVal2->Int32Value(vm);
2482     GTEST_LOG_(INFO) << "str2 : is number : " << jsVal2IsNumber << "  value : " << val2;
2483     Local<JSValueRef> jsVal3 = obj->Get(vm, StringRef::NewFromUtf8(vm, "333"));
2484     int val3 = jsVal3->Int32Value(vm);
2485     GTEST_LOG_(INFO) << "333 : " << val3;
2486     Local<JSValueRef> jsVal4 = obj->Get(vm, StringRef::NewFromUtf8(vm, "444"));
2487     Local<StringRef> val4 = jsVal4->ToString(vm);
2488     GTEST_LOG_(INFO) << "str4 : " << val4->ToString(vm);
2489 
2490     Local<JSValueRef> jsVal8 = obj->Get(vm, StringRef::NewFromUtf8(vm, "b8"));
2491     bool jsVal8IsBool = jsVal8->IsBoolean();
2492     Local<BooleanRef> val8Ref = jsVal8;
2493     bool val8 = val8Ref->Value();
2494     GTEST_LOG_(INFO) << "b8  is bool : " << jsVal8IsBool << "    val : " << val8;
2495 }
2496 
2497 // json对象获取数组。
JsonObjGetArray(EcmaVM * vm,Local<ObjectRef> obj)2498 void JsonObjGetArray(EcmaVM *vm, Local<ObjectRef> obj)
2499 {
2500     Local<JSValueRef> jsVal5 = obj->Get(vm, StringRef::NewFromUtf8(vm, "arr5"));
2501     Local<ObjectRef> val5Obj = jsVal5;
2502     int length = val5Obj->Get(vm, StringRef::NewFromUtf8(vm, "length"))->Int32Value(vm);
2503     GTEST_LOG_(INFO) << "arr5 length : " << length;
2504     for (int i = 0; i < length; ++i) {
2505         Local<JSValueRef> val5Item = val5Obj->Get(vm, NumberRef::New(vm, i));
2506         GTEST_LOG_(INFO) << "arr5 : " << i << "    " << val5Item->Int32Value(vm);
2507     }
2508     Local<ArrayRef> val5Arr = jsVal5;
2509     uint32_t length2 = val5Arr->Length(vm);
2510     GTEST_LOG_(INFO) << "arr5 length2 : " << length2;
2511     for (uint32_t i = 0; i < length2; ++i) {
2512         Local<JSValueRef> val5Item = ArrayRef::GetValueAt(vm, val5Arr, i);
2513         GTEST_LOG_(INFO) << "arr5 : " << i << "    " << val5Item->Int32Value(vm);
2514     }
2515     Local<JSValueRef> jsVal6 = obj->Get(vm, StringRef::NewFromUtf8(vm, "arr6"));
2516     Local<ObjectRef> val6Obj = jsVal6;
2517     int length3 = val6Obj->Get(vm, StringRef::NewFromUtf8(vm, "length"))->Int32Value(vm);
2518     GTEST_LOG_(INFO) << "arr6 length : " << length3;
2519     for (int i = 0; i < length3; ++i) {
2520         Local<JSValueRef> val6Item = val6Obj->Get(vm, NumberRef::New(vm, i));
2521         GTEST_LOG_(INFO) << "arr6 : " << i << "    " << val6Item->ToString(vm)->ToString(vm);
2522     }
2523 }
2524 
2525 // json对象获取对象。
JsonObjGetObject(EcmaVM * vm,Local<ObjectRef> obj)2526 void JsonObjGetObject(EcmaVM *vm, Local<ObjectRef> obj)
2527 {
2528     Local<JSValueRef> jsVal7 = obj->Get(vm, StringRef::NewFromUtf8(vm, "data7"));
2529     Local<ObjectRef> val7Obj = jsVal7->ToObject(vm);
2530     Local<ArrayRef> val7ObjKeys = val7Obj->GetOwnPropertyNames(vm);
2531     for (uint32_t i = 0; i < val7ObjKeys->Length(vm); ++i) {
2532         Local<JSValueRef> itemKey = ArrayRef::GetValueAt(vm, val7ObjKeys, i);
2533         Local<JSValueRef> itemVal = val7Obj->Get(vm, itemKey);
2534         GTEST_LOG_(INFO) << "data7 :   item index:" << i << "    Key:" << itemKey->ToString(vm)->ToString(vm) <<
2535             "    val:" << itemVal->ToString(vm)->ToString(vm);
2536     }
2537 }
2538 
2539 /* demo11 json 测试,json字符串 转 obj。 注意key不能是纯数字。 json:
2540  * {
2541  * "str1": "val1",
2542  * "str2": 222,
2543  * "333": 456,
2544  * "444": "val4",
2545  * "arr5": [
2546  * 51,
2547  * 52,
2548  * 53,
2549  * 54,
2550  * 55
2551  * ],
2552  * "arr6": [
2553  * "str61",
2554  * "str62",
2555  * "str63",
2556  * "str64"
2557  * ],
2558  * "data7": {
2559  * "key71": "val71",
2560  * "key72": "val72"
2561  * },
2562  * "b8": true
2563  * }
2564  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_1_parse_object)2565 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_1_parse_object)
2566 {
2567     GTEST_LOG_(INFO) << "sample_demo11_json_test_1_parse_object =======================================";
2568     LocalScope scope(vm_);
2569     std::string jsonStr =
2570         "{\"str1\":\"val1\",\"str2\":222,\"333\":456,\"444\":\"val4\",\"arr5\":[51,52,53,54,55],\"arr6\":[\"str61\","
2571         "\"str62\",\"str63\",\"str64\"],\"data7\":{\"key71\":\"val71\",\"key72\":\"val72\"},\"b8\":true}";
2572     Local<JSValueRef> jsObj = JSON::Parse(vm_, StringRef::NewFromUtf8(vm_, jsonStr.c_str()));
2573     Local<ObjectRef> obj = jsObj->ToObject(vm_);
2574 
2575     JsonObjGetValue(vm_, obj);
2576     JsonObjGetArray(vm_, obj);
2577     JsonObjGetObject(vm_, obj);
2578 
2579     GTEST_LOG_(INFO) << "sample_demo11_json_test_1_parse_object =======================================";
2580 }
2581 
2582 /* demo11 json 测试,obj转json字符串。 json:
2583  * {
2584  * "key1": "val1",
2585  * "key2": 123,
2586  * "333": "val3",
2587  * "arr4": [
2588  * "val40",
2589  * "val41",
2590  * "val42",
2591  * "val43"
2592  * ],
2593  * "arr5": [
2594  * 50,
2595  * 51,
2596  * 52,
2597  * 53
2598  * ],
2599  * "b6": true,
2600  * "obj7": {
2601  * "key71": "val71",
2602  * "key72": "val72",
2603  * "key73": "val73"
2604  * }
2605  * }
2606  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_2_stringify_object)2607 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_2_stringify_object)
2608 {
2609     GTEST_LOG_(INFO) << "sample_demo11_json_test_2_stringify_object =======================================";
2610     LocalScope scope(vm_);
2611 
2612     Local<ObjectRef> obj = ObjectRef::New(vm_);
2613     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val1"));
2614     int num2 = 123; // random number
2615     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), NumberRef::New(vm_, num2));
2616     int num3 = 333; // random number
2617     obj->Set(vm_, NumberRef::New(vm_, num3), StringRef::NewFromUtf8(vm_, "val3"));
2618 
2619     Local<ArrayRef> arr4 = ArrayRef::New(vm_);
2620     ArrayRef::SetValueAt(vm_, arr4, 0, StringRef::NewFromUtf8(vm_, "val40"));
2621     ArrayRef::SetValueAt(vm_, arr4, 1, StringRef::NewFromUtf8(vm_, "val41"));
2622     ArrayRef::SetValueAt(vm_, arr4, 2, StringRef::NewFromUtf8(vm_, "val42"));
2623     ArrayRef::SetValueAt(vm_, arr4, 3, StringRef::NewFromUtf8(vm_, "val43"));
2624     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "arr4"), arr4);
2625 
2626     Local<ArrayRef> arr5 = ArrayRef::New(vm_);
2627     int num50 = 50; // random number
2628     int num51 = 51; // random number
2629     int num52 = 52; // random number
2630     int num53 = 53; // random number
2631     ArrayRef::SetValueAt(vm_, arr5, 0, IntegerRef::New(vm_, num50));
2632     ArrayRef::SetValueAt(vm_, arr5, 1, IntegerRef::New(vm_, num51));
2633     ArrayRef::SetValueAt(vm_, arr5, 2, IntegerRef::New(vm_, num52));
2634     ArrayRef::SetValueAt(vm_, arr5, 3, IntegerRef::New(vm_, num53));
2635     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "arr5"), arr5);
2636 
2637     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "b6"), BooleanRef::New(vm_, true));
2638 
2639     Local<ObjectRef> obj7 = ObjectRef::New(vm_);
2640     obj7->Set(vm_, StringRef::NewFromUtf8(vm_, "key71"), StringRef::NewFromUtf8(vm_, "val71"));
2641     obj7->Set(vm_, StringRef::NewFromUtf8(vm_, "key72"), StringRef::NewFromUtf8(vm_, "val72"));
2642     obj7->Set(vm_, StringRef::NewFromUtf8(vm_, "key73"), StringRef::NewFromUtf8(vm_, "val73"));
2643 
2644     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "obj7"), obj7);
2645 
2646     Local<JSValueRef> jsStr = JSON::Stringify(vm_, obj);
2647     GTEST_LOG_(INFO) << "jsStr is String : " << jsStr->IsString(vm_);
2648     Local<StringRef> strRef = jsStr->ToString(vm_);
2649     std::string str = strRef->ToString(vm_);
2650     GTEST_LOG_(INFO) << "json : " << str;
2651 
2652     GTEST_LOG_(INFO) << "sample_demo11_json_test_2_stringify_object =======================================";
2653 }
2654 
2655 /* demo11 json 测试,json字符串转为数组。 json:
2656  * [51,52,53,54,55]
2657  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_3_parse_array1)2658 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array1)
2659 {
2660     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array1 =======================================";
2661     LocalScope scope(vm_);
2662 
2663     // 随机的一个 json 数字 数组。  [51,52,53,54,55]
2664     Local<StringRef> arrStr1 = StringRef::NewFromUtf8(vm_, "[51,52,53,54,55]");
2665     Local<JSValueRef> jsArr1 = JSON::Parse(vm_, arrStr1);
2666     bool jsArr1IsArr = jsArr1->IsArray(vm_);
2667     GTEST_LOG_(INFO) << "jsArr1 is array : " << jsArr1IsArr;
2668     Local<ArrayRef> arr1 = jsArr1;
2669     uint32_t arr1Length = arr1->Length(vm_);
2670     GTEST_LOG_(INFO) << "arr1 length : " << arr1Length;
2671     for (uint32_t i = 0; i < arr1Length; ++i) {
2672         Local<JSValueRef> arr1Item = ArrayRef::GetValueAt(vm_, arr1, i);
2673         if (arr1Item->IsNumber()) {
2674             int num = arr1Item->Int32Value(vm_);
2675             GTEST_LOG_(INFO) << "arr1 index : " << i << "  value : " << num;
2676         } else {
2677             GTEST_LOG_(INFO) << "arr1 index : " << i << "  not number !";
2678         }
2679     }
2680     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array1 =======================================";
2681 }
2682 
2683 /* demo11 json 测试,json字符串转为数组。 json:
2684  * ["a1","a2","a3","a4","a5","a6"]
2685  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_3_parse_array2)2686 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array2)
2687 {
2688     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array2 =======================================";
2689     LocalScope scope(vm_);
2690 
2691     // 随机的一个json字符串数组。 ["a1","a2","a3","a4","a5","a6"]
2692     Local<StringRef> arrStr2 = StringRef::NewFromUtf8(vm_, "[\"a1\",\"a2\",\"a3\",\"a4\",\"a5\",\"a6\"]");
2693     Local<JSValueRef> jsArr2 = JSON::Parse(vm_, arrStr2);
2694     bool jsArr2IsArr = jsArr2->IsArray(vm_);
2695     GTEST_LOG_(INFO) << "jsArr2 is array : " << jsArr2IsArr;
2696     Local<ArrayRef> arr2 = jsArr2;
2697     uint32_t arr2Length = arr2->Length(vm_);
2698     GTEST_LOG_(INFO) << "arr2 length : " << arr2Length;
2699     for (uint32_t i = 0; i < arr2Length; ++i) {
2700         Local<JSValueRef> arr2Item = ArrayRef::GetValueAt(vm_, arr2, i);
2701         std::string str = arr2Item->ToString(vm_)->ToString(vm_);
2702         GTEST_LOG_(INFO) << "arr2 index : " << i << "  value : " << str;
2703     }
2704 
2705     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array2 =======================================";
2706 }
2707 
2708 /* demo11 json 测试,json字符串转为数组。 json:
2709  * [true,true,false,false,true]
2710  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_3_parse_array3)2711 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array3)
2712 {
2713     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array3 =======================================";
2714     LocalScope scope(vm_);
2715     Local<StringRef> arrStr3 = StringRef::NewFromUtf8(vm_, "[true,true,false,false,true]");
2716     Local<JSValueRef> jsArr3 = JSON::Parse(vm_, arrStr3);
2717     bool jsArr3IsArr = jsArr3->IsArray(vm_);
2718     GTEST_LOG_(INFO) << "jsArr3 is array : " << jsArr3IsArr;
2719     Local<ArrayRef> arr3 = jsArr3;
2720     uint32_t arr3Length = arr3->Length(vm_);
2721     GTEST_LOG_(INFO) << "arr3 length : " << arr3Length;
2722     for (uint32_t i = 0; i < arr3Length; ++i) {
2723         Local<JSValueRef> arr3Item = ArrayRef::GetValueAt(vm_, arr3, i);
2724         int b = arr3Item->BooleaValue(vm_);
2725         GTEST_LOG_(INFO) << "arr3 index : " << i << "  value : " << b;
2726     }
2727     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array3 =======================================";
2728 }
2729 
2730 /* demo11 json 测试,json字符串转为数组。 json:
2731  * [
2732  * {
2733  * "key1": "val11",
2734  * "key2": "val12"
2735  * },
2736  * {
2737  * "key1": "val21",
2738  * "key2": "val22"
2739  * },
2740  * {
2741  * "key1": "val31",
2742  * "key2": "val32"
2743  * }
2744  * ]
2745  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_3_parse_array4)2746 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array4)
2747 {
2748     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array4 =======================================";
2749     LocalScope scope(vm_);
2750 
2751     // json 对象数组。
2752     // json: [{"key1": "val11","key2": "val12"},{"key1": "val21","key2": "val22"},{"key1": "val31","key2": "val32"}]
2753     Local<StringRef> arrStr4 =
2754         StringRef::NewFromUtf8(vm_, "[{\"key1\":\"val11\",\"key2\":\"val12\"},{\"key1\":\"val21\",\"key2\":\"val22\"},{"
2755         "\"key1\":\"val31\",\"key2\":\"val32\"}]");
2756     Local<JSValueRef> jsArr4 = JSON::Parse(vm_, arrStr4);
2757     bool jsArr4IsArr = jsArr4->IsArray(vm_);
2758     GTEST_LOG_(INFO) << "jsArr4 is array : " << jsArr4IsArr;
2759     Local<ArrayRef> arr4 = jsArr4;
2760     uint32_t arr4Length = arr4->Length(vm_);
2761     GTEST_LOG_(INFO) << "arr4 length : " << arr4Length;
2762     for (uint32_t i = 0; i < arr4Length; ++i) {
2763         Local<JSValueRef> jsArr4Item = ArrayRef::GetValueAt(vm_, arr4, i);
2764         Local<ObjectRef> obj = jsArr4Item->ToObject(vm_);
2765 
2766         Local<JSValueRef> objVal1 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key1"));
2767         Local<JSValueRef> objVal2 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key2"));
2768 
2769         GTEST_LOG_(INFO) << "arr4 index : " << i << "  key1 : " << objVal1->ToString(vm_)->ToString(vm_);
2770         GTEST_LOG_(INFO) << "arr4 index : " << i << "  key2 : " << objVal2->ToString(vm_)->ToString(vm_);
2771     }
2772 
2773     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array4 =======================================";
2774 }
2775 
2776 /* demo11 json 测试,json字符串转为数组。 json:
2777  * ["val1",222,true,{"key1": "val1","key2": "val2"}]
2778  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_3_parse_array5)2779 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array5)
2780 {
2781     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array5 =======================================";
2782     LocalScope scope(vm_);
2783 
2784     // json 数组: ["val1",222,true,{"key1": "val1","key2": "val2"}]
2785     Local<StringRef> arrStr5 = StringRef::NewFromUtf8(vm_, "[\"val1\",222,true,{\"key1\":\"val1\",\"key2\":\"val1\"}]");
2786     Local<JSValueRef> jsArr5 = JSON::Parse(vm_, arrStr5);
2787     bool jsArr5IsArr = jsArr5->IsArray(vm_);
2788     GTEST_LOG_(INFO) << "jsArr5 is array : " << jsArr5IsArr;
2789     Local<ArrayRef> arr5 = jsArr5;
2790     uint32_t arr5Length = arr5->Length(vm_);
2791     GTEST_LOG_(INFO) << "arr5 length : " << arr5Length;
2792     for (uint32_t i = 0; i < arr5Length; ++i) {
2793         Local<JSValueRef> arr5Item = ArrayRef::GetValueAt(vm_, arr5, i);
2794         if (arr5Item->IsString(vm_)) {
2795             GTEST_LOG_(INFO) << "arr5 index : " << i << "  value : " << arr5Item->ToString(vm_)->ToString(vm_);
2796         } else if (arr5Item->IsNumber()) {
2797             GTEST_LOG_(INFO) << "arr5 index : " << i << "  value : " << arr5Item->Int32Value(vm_);
2798         } else if (arr5Item->IsBoolean()) {
2799             GTEST_LOG_(INFO) << "arr5 index : " << i << "  value : " << arr5Item->ToBoolean(vm_)->Value();
2800         } else if (arr5Item->IsObject(vm_)) {
2801             Local<ObjectRef> obj = arr5Item->ToObject(vm_);
2802             Local<ObjectRef> val1 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key1"));
2803             Local<ObjectRef> val2 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key2"));
2804             GTEST_LOG_(INFO) << "arr5 index : " << i << "  key1 : " << val1->ToString(vm_)->ToString(vm_);
2805             GTEST_LOG_(INFO) << "arr5 index : " << i << "  key2 : " << val2->ToString(vm_)->ToString(vm_);
2806         } else {
2807             GTEST_LOG_(INFO) << "arr5 index : " << i << "  not type !";
2808         }
2809     }
2810     GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array5 =======================================";
2811 }
2812 
2813 /* demo11 json 测试,数组转json字符串。 json:
2814  * ["val0","val1","val2","val3"]
2815  * [
2816  * {
2817  * "key1": "val11",
2818  * "key2": "val12",
2819  * "key3": "val13"
2820  * },
2821  * {
2822  * "key1": "val21",
2823  * "key2": "val22",
2824  * "key3": "val23"
2825  * }
2826  * ]
2827  * [
2828  * "val1",
2829  * 222,
2830  * true,
2831  * {
2832  * "key1": "val1",
2833  * "key2": "val2"
2834  * }
2835  * ]
2836  */
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_4_stringify_array1)2837 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_4_stringify_array1)
2838 {
2839     GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array1 =======================================";
2840     LocalScope scope(vm_);
2841     Local<ArrayRef> arr = ArrayRef::New(vm_);
2842     ArrayRef::SetValueAt(vm_, arr, 0, StringRef::NewFromUtf8(vm_, "val0"));
2843     ArrayRef::SetValueAt(vm_, arr, 1, StringRef::NewFromUtf8(vm_, "val1"));
2844     ArrayRef::SetValueAt(vm_, arr, 2, StringRef::NewFromUtf8(vm_, "val2"));
2845     ArrayRef::SetValueAt(vm_, arr, 3, StringRef::NewFromUtf8(vm_, "val3"));
2846     Local<JSValueRef> json1 = JSON::Stringify(vm_, arr);
2847     GTEST_LOG_(INFO) << " js arr 1 json : " << json1->ToString(vm_)->ToString(vm_);
2848     GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array1 =======================================";
2849 }
2850 
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_4_stringify_array2)2851 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_4_stringify_array2)
2852 {
2853     GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array2 =======================================";
2854     Local<ObjectRef> obj1 = ObjectRef::New(vm_);
2855     obj1->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val11"));
2856     obj1->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), StringRef::NewFromUtf8(vm_, "val12"));
2857     obj1->Set(vm_, StringRef::NewFromUtf8(vm_, "key3"), StringRef::NewFromUtf8(vm_, "val13"));
2858     Local<ObjectRef> obj2 = ObjectRef::New(vm_);
2859     obj2->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val21"));
2860     obj2->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), StringRef::NewFromUtf8(vm_, "val22"));
2861     obj2->Set(vm_, StringRef::NewFromUtf8(vm_, "key3"), StringRef::NewFromUtf8(vm_, "val23"));
2862     Local<ArrayRef> arr = ArrayRef::New(vm_);
2863     ArrayRef::SetValueAt(vm_, arr, 0, obj1);
2864     ArrayRef::SetValueAt(vm_, arr, 1, obj2);
2865     Local<JSValueRef> json2 = JSON::Stringify(vm_, arr);
2866     GTEST_LOG_(INFO) << " js arr 2 json : " << json2->ToString(vm_)->ToString(vm_);
2867     GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array2 =======================================";
2868 }
2869 
HWTEST_F_L0(JSNApiSampleTest,sample_demo11_json_test_4_stringify_array3)2870 HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_4_stringify_array3)
2871 {
2872     GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array3 =======================================";
2873     Local<ObjectRef> obj = ObjectRef::New(vm_);
2874     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val1"));
2875     obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), StringRef::NewFromUtf8(vm_, "val2"));
2876     Local<ArrayRef> arr = ArrayRef::New(vm_);
2877     ArrayRef::SetValueAt(vm_, arr, 0, StringRef::NewFromUtf8(vm_, "val1"));
2878     int num2 = 222; // random number
2879     ArrayRef::SetValueAt(vm_, arr, 1, NumberRef::New(vm_, num2));
2880     ArrayRef::SetValueAt(vm_, arr, 2, BooleanRef::New(vm_, true));
2881     ArrayRef::SetValueAt(vm_, arr, 3, obj);
2882     Local<JSValueRef> json3 = JSON::Stringify(vm_, arr);
2883     GTEST_LOG_(INFO) << " js arr 3 json : " << json3->ToString(vm_)->ToString(vm_);
2884     GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array3 =======================================";
2885 }
2886 
2887 /* demo12 异常的抛出和处理 */
2888 // 抛出异常的测试函数
ThrowErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2889 Local<JSValueRef> ThrowErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2890 {
2891     int i = par->Int32Value(vm);
2892     if (i == 0) {
2893         std::string errStr = std::string("function:").append(__func__).append("err:Error");
2894         Local<JSValueRef> error = Exception::Error(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2895         JSNApi::ThrowException(vm, error);
2896         return JSValueRef::Undefined(vm);
2897     }
2898     int num = 2; // 函数的功能,原数字的2倍。
2899     return NumberRef::New(vm, i * num);
2900 }
2901 
ThrowRangeErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2902 Local<JSValueRef> ThrowRangeErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2903 {
2904     int i = par->Int32Value(vm);
2905     if (i == 0) {
2906         std::string errStr = std::string("function:").append(__func__).append("err:RangeError");
2907         Local<JSValueRef> error = Exception::RangeError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2908         JSNApi::ThrowException(vm, error);
2909         return JSValueRef::Undefined(vm);
2910     }
2911     int num = 2; // 函数的功能,原数字的2倍。
2912     return NumberRef::New(vm, i * num);
2913 }
2914 
ThrowReferenceErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2915 Local<JSValueRef> ThrowReferenceErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2916 {
2917     int i = par->Int32Value(vm);
2918     if (i == 0) {
2919         std::string errStr = std::string("function:").append(__func__).append("err:ReferenceError");
2920         Local<JSValueRef> error = Exception::ReferenceError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2921         JSNApi::ThrowException(vm, error);
2922         return JSValueRef::Undefined(vm);
2923     }
2924     int num = 2; // 函数的功能,原数字的2倍。
2925     return NumberRef::New(vm, i * num);
2926 }
2927 
ThrowSyntaxErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2928 Local<JSValueRef> ThrowSyntaxErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2929 {
2930     int i = par->Int32Value(vm);
2931     if (i == 0) {
2932         std::string errStr = std::string("function:").append(__func__).append("err:SyntaxError");
2933         Local<JSValueRef> error = Exception::SyntaxError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2934         JSNApi::ThrowException(vm, error);
2935         return JSValueRef::Undefined(vm);
2936     }
2937     int num = 2; // 函数的功能,原数字的2倍。
2938     return NumberRef::New(vm, i * num);
2939 }
2940 
ThrowTypeErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2941 Local<JSValueRef> ThrowTypeErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2942 {
2943     int i = par->Int32Value(vm);
2944     if (i == 0) {
2945         std::string errStr = std::string("function:").append(__func__).append("err:TypeError");
2946         Local<JSValueRef> error = Exception::TypeError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2947         JSNApi::ThrowException(vm, error);
2948         return JSValueRef::Undefined(vm);
2949     }
2950     int num = 2; // 函数的功能,原数字的2倍。
2951     return NumberRef::New(vm, i * num);
2952 }
2953 
ThrowAggregateErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2954 Local<JSValueRef> ThrowAggregateErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2955 {
2956     int i = par->Int32Value(vm);
2957     if (i == 0) {
2958         std::string errStr = std::string("function:").append(__func__).append("err:AggregateError");
2959         Local<JSValueRef> error = Exception::AggregateError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2960         JSNApi::ThrowException(vm, error);
2961         return JSValueRef::Undefined(vm);
2962     }
2963     int num = 2; // 函数的功能,原数字的2倍。
2964     return NumberRef::New(vm, i * num);
2965 }
2966 
ThrowEvalErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2967 Local<JSValueRef> ThrowEvalErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2968 {
2969     int i = par->Int32Value(vm);
2970     if (i == 0) {
2971         std::string errStr = std::string("function:").append(__func__).append("err:EvalError");
2972         Local<JSValueRef> error = Exception::EvalError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2973         JSNApi::ThrowException(vm, error);
2974         return JSValueRef::Undefined(vm);
2975     }
2976     int num = 2; // 函数的功能,原数字的2倍。
2977     return NumberRef::New(vm, i * num);
2978 }
2979 
ThrowOOMErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2980 Local<JSValueRef> ThrowOOMErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2981 {
2982     int i = par->Int32Value(vm);
2983     if (i == 0) {
2984         std::string errStr = std::string("function:").append(__func__).append("err:OOMError");
2985         Local<JSValueRef> error = Exception::OOMError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2986         JSNApi::ThrowException(vm, error);
2987         return JSValueRef::Undefined(vm);
2988     }
2989     int num = 2; // 函数的功能,原数字的2倍。
2990     return NumberRef::New(vm, i * num);
2991 }
2992 
ThrowTerminationErrorFuncTest(const EcmaVM * vm,Local<NumberRef> par)2993 Local<JSValueRef> ThrowTerminationErrorFuncTest(const EcmaVM *vm, Local<NumberRef> par)
2994 {
2995     int i = par->Int32Value(vm);
2996     if (i == 0) {
2997         std::string errStr = std::string("function:").append(__func__).append("err:TerminationError");
2998         Local<JSValueRef> error = Exception::TerminationError(vm, StringRef::NewFromUtf8(vm, errStr.c_str()));
2999         JSNApi::ThrowException(vm, error);
3000         return JSValueRef::Undefined(vm);
3001     }
3002     int num = 2; // 函数的功能,原数字的2倍。
3003     return NumberRef::New(vm, i * num);
3004 }
3005 
3006 // 处理异常,用 JSNApi 类中的函数。
ClearAndPrintException4JSNApi(const EcmaVM * vm,const std::string log)3007 void ClearAndPrintException4JSNApi(const EcmaVM *vm, const std::string log)
3008 {
3009     if (!JSNApi::HasPendingException(vm)) {
3010         GTEST_LOG_(INFO) << log << " no exception .";
3011         return;
3012     }
3013 
3014     JSNApi::PrintExceptionInfo(vm);
3015     Local<ObjectRef> exception = JSNApi::GetAndClearUncaughtException(vm);
3016     std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm);
3017     std::string exceptionMessage = exception->Get(vm, StringRef::NewFromUtf8(vm,
3018         "message"))->ToString(vm)->ToString(vm);
3019     std::string exceptionStack = exception->Get(vm,
3020         StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm);
3021 
3022     GTEST_LOG_(INFO) << log << " exception name : " << exceptionName;
3023     GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage;
3024     GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack;
3025 };
3026 
3027 // 处理异常,用 TryCatch 类中的函数。
ClearAndPrintException4TryCatch1(const EcmaVM * vm,const std::string log)3028 void ClearAndPrintException4TryCatch1(const EcmaVM *vm, const std::string log)
3029 {
3030     TryCatch tryCatch(vm);
3031     if (!tryCatch.HasCaught()) {
3032         GTEST_LOG_(INFO) << log << " no exception .";
3033         return;
3034     }
3035     Local<ObjectRef> exception = tryCatch.GetAndClearException();
3036     std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm);
3037     std::string exceptionMessage = exception->Get(vm,
3038         StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm);
3039     std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm);
3040 
3041     GTEST_LOG_(INFO) << log << " exception name : " << exceptionName;
3042     GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage;
3043     GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack;
3044 };
3045 
3046 // 处理异常,用 TryCatch 类中的函数。
ClearAndPrintException4TryCatch2(const EcmaVM * vm,const std::string log)3047 void ClearAndPrintException4TryCatch2(const EcmaVM *vm, const std::string log)
3048 {
3049     TryCatch tryCatch(vm);
3050     if (!tryCatch.HasCaught()) {
3051         GTEST_LOG_(INFO) << log << " no exception .";
3052         return;
3053     }
3054 
3055     Local<ObjectRef> exception = tryCatch.GetException();
3056     tryCatch.ClearException();
3057     std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm);
3058     std::string exceptionMessage = exception->Get(vm,
3059         StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm);
3060     std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm);
3061 
3062     GTEST_LOG_(INFO) << log << " exception name : " << exceptionName;
3063     GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage;
3064     GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack;
3065     tryCatch.Rethrow();
3066 };
3067 
3068 // 异常没有处理重新抛出异常,用 TryCatch 类中的函数。
PrintAndRethrowException4TryCatch3(const EcmaVM * vm,const std::string log)3069 void PrintAndRethrowException4TryCatch3(const EcmaVM *vm, const std::string log)
3070 {
3071     TryCatch tryCatch(vm);
3072     if (!tryCatch.HasCaught()) {
3073         GTEST_LOG_(INFO) << log << " no exception .";
3074         return;
3075     }
3076 
3077     Local<ObjectRef> exception = tryCatch.GetAndClearException();
3078     std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm);
3079     std::string exceptionMessage = exception->Get(vm,
3080         StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm);
3081     std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm);
3082 
3083     GTEST_LOG_(INFO) << log << " exception name : " << exceptionName;
3084     GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage;
3085     GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack;
3086     tryCatch.Rethrow();
3087 };
3088 
3089 /* demo12 异常的抛出和处理 */
HWTEST_F_L0(JSNApiSampleTest,sample_demo12_exception_test)3090 HWTEST_F_L0(JSNApiSampleTest, sample_demo12_exception_test)
3091 {
3092     GTEST_LOG_(INFO) << "sample_demo12_exception_test =======================================";
3093     LocalScope scope(vm_);
3094     // Error
3095     Local<JSValueRef> exception1 = ThrowErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3096     if (exception1->IsUndefined()) {
3097         ClearAndPrintException4JSNApi(vm_, "ThrowErrorFuncTest");
3098     }
3099     // RangeError
3100     Local<JSValueRef> exception2 = ThrowRangeErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3101     if (exception2->IsUndefined()) {
3102         ClearAndPrintException4TryCatch1(vm_, "ThrowRangeErrorFuncTest");
3103     }
3104     // ReferenceError
3105     Local<JSValueRef> exception3 = ThrowReferenceErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3106     if (exception3->IsUndefined()) {
3107         ClearAndPrintException4TryCatch2(vm_, "ThrowReferenceErrorFuncTest");
3108     }
3109     // SyntaxError
3110     Local<JSValueRef> exception4 = ThrowSyntaxErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3111     if (exception4->IsUndefined()) {
3112         PrintAndRethrowException4TryCatch3(vm_, "ThrowSyntaxErrorFuncTest");
3113         ClearAndPrintException4TryCatch1(vm_, "ThrowSyntaxErrorFuncTest");
3114     }
3115     // TypeError
3116     Local<JSValueRef> exception5 = ThrowTypeErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3117     if (exception5->IsUndefined()) {
3118         ClearAndPrintException4TryCatch1(vm_, "ThrowTypeErrorFuncTest");
3119     }
3120     // AggregateError
3121     Local<JSValueRef> exception6 = ThrowAggregateErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3122     if (exception6->IsUndefined()) {
3123         ClearAndPrintException4TryCatch1(vm_, "ThrowAggregateErrorFuncTest");
3124     }
3125     // EvalError
3126     Local<JSValueRef> exception7 = ThrowEvalErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3127     if (exception7->IsUndefined()) {
3128         ClearAndPrintException4TryCatch1(vm_, "ThrowEvalErrorFuncTest");
3129     }
3130     // OOMError
3131     Local<JSValueRef> exception8 = ThrowOOMErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3132     if (exception8->IsUndefined()) {
3133         ClearAndPrintException4TryCatch1(vm_, "ThrowOOMErrorFuncTest");
3134     }
3135     // TerminationError
3136     Local<JSValueRef> exception9 = ThrowTerminationErrorFuncTest(vm_, NumberRef::New(vm_, 0));
3137     if (exception9->IsUndefined()) {
3138         ClearAndPrintException4TryCatch1(vm_, "ThrowTerminationErrorFuncTest");
3139     }
3140     GTEST_LOG_(INFO) << "sample_demo12_exception_test =======================================";
3141 }
3142 }