/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "gtest/gtest.h" #include "assembler/assembly-parser.h" #include "ecmascript/builtins/builtins.h" #include "ecmascript/builtins/builtins_function.h" #include "ecmascript/builtins/builtins_locale.h" #include "ecmascript/compiler/aot_file/an_file_data_manager.h" #include "ecmascript/compiler/aot_file/aot_file_manager.h" #include "ecmascript/ecma_global_storage.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" #include "ecmascript/js_api/js_api_deque.h" #include "ecmascript/js_api/js_api_queue.h" #include "ecmascript/js_bigint.h" #include "ecmascript/js_generator_object.h" #include "ecmascript/js_list_format.h" #include "ecmascript/js_runtime_options.h" #include "ecmascript/js_thread.h" #include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/napi/include/jsnapi.h" #include "ecmascript/napi/jsnapi_helper.h" #include "ecmascript/object_factory.h" #include "ecmascript/tagged_array.h" #include "ecmascript/tests/test_helper.h" using namespace panda; using namespace panda::ecmascript; using namespace panda::pandasm; using namespace panda::panda_file; namespace panda::test { class JSNApiSampleTest : public testing::Test { public: void SetUp() override { RuntimeOption option; option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR); vm_ = JSNApi::CreateJSVM(option); thread_ = vm_->GetJSThread(); vm_->SetEnableForceGC(true); } void TearDown() override { vm_->SetEnableForceGC(false); JSNApi::DestroyJSVM(vm_); } protected: JSThread *thread_ = nullptr; EcmaVM *vm_ = nullptr; }; /* demo1 原始类型的使用。 */ HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_IntegerRef) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_int============================================================="; int inputInt = 123; // int value = 123 Local intObject = IntegerRef::New(vm_, inputInt); int intValue = intObject->Value(); GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_intValue : " << intValue; Local pintObject = intObject; GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_pintObject_IsInt : " << pintObject->IsInt(); GTEST_LOG_(INFO) << "sample_primitive_IntegerRef_uint============================================================"; uint inputUint = 123; // uint value = 123 Local uintObject = IntegerRef::NewFromUnsigned(vm_, inputUint); int uintValue = uintObject->Value(); GTEST_LOG_(INFO) << "sample_primitive_uintValue : " << uintValue; } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_NumberRef) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_double==========================================================="; double inputDouble = 3.14; // double value = 3.14 Local doubleObject = NumberRef::New(vm_, inputDouble); double doubleValue = doubleObject->Value(); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_doubleValue : " << doubleValue; Local pdoubleObject = doubleObject; GTEST_LOG_(INFO) << "sample_primitive_NumberRef_pdoubleObject_IsNumber : " << pdoubleObject->IsNumber(); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int32_t=========================================================="; int32_t inputInt32t = 666; // int32-t value = 666 Local int32tObject = NumberRef::New(vm_, inputInt32t); double int32tValue = int32tObject->Value(); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int32tValue : " << int32tValue; Local pint32tObject = int32tObject; GTEST_LOG_(INFO) << "sample_primitive_NumberRef_pint32tObject_Int32Value : " << pint32tObject->Int32Value(vm_); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_uint32_t========================================================="; uint32_t inputUint32t = 666; // uint32_t value = 666 Local uint32tObject = NumberRef::New(vm_, inputUint32t); double uint32tValue = uint32tObject->Value(); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_uint32tValue : " << uint32tValue; Local puint32tObject = uint32tObject; GTEST_LOG_(INFO) << "sample_primitive_NumberRef_puint32tObject_Uint32Value : " << puint32tObject->Uint32Value(vm_); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int64_t=========================================================="; int64_t inputInt64t = 666; // int64_t value = 666 Local int64tObject = NumberRef::New(vm_, inputInt64t); double int64tValue = int64tObject->Value(); GTEST_LOG_(INFO) << "sample_primitive_NumberRef_int64tValue : " << int64tValue; } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_BigIntRef_Uint64) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_uint64_t========================================================="; uint64_t inputUint64t = 999; // uint64_t value = 999 Local uint64tObject = BigIntRef::New(vm_, inputUint64t); int64_t ucValue = 0; bool uLossless = true; uint64_t ucValue1 = 0; uint64tObject->BigIntToInt64(vm_, &ucValue, &uLossless); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToInt64 : " << ucValue; uint64tObject->BigIntToUint64(vm_, &ucValue1, &uLossless); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToUint64 : " << ucValue1; bool uSign = false; uint32_t uSize = 3; int uarraySize = 3; const uint64_t uWords[3] = {666, 777, 888}; Local ubigWords = BigIntRef::CreateBigWords(vm_, uSign, uSize, uWords); for (int i = 0; i < uarraySize; i++) { GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_UwordsArrayindex" << " [ " << i << " ] : " << uWords[i]; } Local ubigWordsRef(ubigWords); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_UArraySize : " << ubigWordsRef->GetWordsArraySize(vm_); bool uresultSignBit = true; int unewarraySize = 3; uint64_t *uresultWords = new uint64_t[unewarraySize](); ubigWordsRef->GetWordsArray(vm_, &uresultSignBit, uSize, uresultWords); for (int i = 0; i < unewarraySize; i++) { GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_uresultWords" << " [ " << i << " ] : " << uresultWords[i]; } } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_BigIntRef_Int64) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_int64_t=========================================================="; int64_t inputInt64t = 111; // int64_t value = 111 Local int64tObject = BigIntRef::New(vm_, inputInt64t); int64_t icValue = 0; bool iLossless = true; uint64_t icValue1 = 0; int64tObject->BigIntToInt64(vm_, &icValue, &iLossless); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToInt64 : " << icValue; int64tObject->BigIntToUint64(vm_, &icValue1, &iLossless); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_BigIntToUint64 : " << icValue1; bool iSign = false; uint32_t iSize = 3; int iarraySize = 3; const uint64_t iWords[3] = {222, 333, 444}; Local ibigWords = BigIntRef::CreateBigWords(vm_, iSign, iSize, iWords); for (int i = 0; i < iarraySize; i++) { GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_iWordsArrayindex" << " [ " << i << " ] : " << iWords[i]; } Local ibigWordsRef(ibigWords); GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_iarraySize : " << ibigWordsRef->GetWordsArraySize(vm_); bool iresultSignBit = true; int inewarraySize = 3; uint64_t *iresultWords = new uint64_t[inewarraySize](); ibigWordsRef->GetWordsArray(vm_, &iresultSignBit, iSize, iresultWords); for (int i = 0; i < inewarraySize; i++) { GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_iresultWords" << " [ " << i << " ] : " << iresultWords[i]; } Local pint64tObject = int64tObject; GTEST_LOG_(INFO) << "sample_primitive_BigIntRef_pint64tObject_IsBigInt : " << pint64tObject->IsBigInt(vm_); } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_BooleanRef) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_true============================================================"; Local trueObject = BooleanRef::New(vm_, true); GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_trueObject_Value : " << trueObject->Value(); Local ptrueObject = trueObject; GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_ptrueObject_IsBoolean : " << ptrueObject->IsBoolean(); GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_false==========================================================="; Local falseObject = BooleanRef::New(vm_, false); GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_falseObject_Value : " << falseObject->Value(); Local pfalseObject = falseObject; GTEST_LOG_(INFO) << "sample_primitive_BooleanRef_pfalseObject_IsBoolean : " << pfalseObject->IsBoolean(); } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_StringRef_Char) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char============================================================="; char utf8[12] = "Hello world"; Local local = StringRef::NewFromUtf8(vm_, utf8); JSValueRef *jsValue = (*local); StringRef *charObject = StringRef::Cast(jsValue); EXPECT_EQ(charObject->Utf8Length(vm_), 12); char buffer[12]; EXPECT_EQ(charObject->WriteUtf8(vm_, buffer, 12), 12); std::string res(buffer); GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject : " << res; std::string charObjectStr = charObject->ToString(vm_); GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_ToString : " << charObjectStr; uint32_t charSize = charObject->Length(vm_); GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_Length : " << charSize; char cs[16] = {0}; uint32_t length = charObject->WriteLatin1(vm_, cs, 12); GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_WriteLatin1 : " << length; Local napiWrapperString = charObject->GetNapiWrapperString(vm_); EXPECT_EQ(napiWrapperString->Utf8Length(vm_), 13); char buffer1[12]; EXPECT_EQ(charObject->WriteUtf8(vm_, buffer1, 12), 12); std::string res1(buffer1); GTEST_LOG_(INFO) << "sample_primitive_StringRef_charObject_GetNapiWrapperString : " << res1; PrimitiveRef *pcharObject = charObject; GTEST_LOG_(INFO) << "sample_primitive_StringRef_pcharObject_IsString : " << pcharObject->IsString(vm_); } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_StringRef_Char16) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16_t========================================================="; const char16_t *utf16 = u"Hi,ABCDEF"; Local local = StringRef::NewFromUtf16(vm_, utf16); JSValueRef *jsValue = (*local); StringRef *char16tObject = StringRef::Cast(jsValue); EXPECT_EQ(char16tObject->Utf8Length(vm_), 10); char16_t buffer2[10]; EXPECT_EQ(char16tObject->WriteUtf16(vm_, buffer2, 9), 9); std::string res2(buffer2, buffer2 + sizeof(buffer2) / sizeof(char16_t)); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject : " << res2 << std::endl; std::string char16tObjectStr = char16tObject->ToString(vm_); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject_ToString : " << char16tObjectStr; uint32_t charSize = char16tObject->Length(vm_); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject_Length : " << charSize; char cs1[10] = {0}; uint32_t length = char16tObject->WriteLatin1(vm_, cs1, 10); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject_WriteLatin1 : " << length; Local napiWrapperString = char16tObject->GetNapiWrapperString(vm_); EXPECT_EQ(napiWrapperString->Utf8Length(vm_), 13); char16_t buffer3[10]; EXPECT_EQ(char16tObject->WriteUtf16(vm_, buffer3, 9), 9); std::string res3(buffer3, buffer3 + sizeof(buffer3) / sizeof(char16_t)); GTEST_LOG_(INFO) << "sample_primitive_StringRef_char16tObject : " << res3; PrimitiveRef *pchar16tObject = char16tObject; GTEST_LOG_(INFO) << "sample_primitive_StringRef_pchar16tObject_IsString : " << pchar16tObject->IsString(vm_); } HWTEST_F_L0(JSNApiSampleTest, Sample_PrimitiveRef_SymbolRef) { LocalScope scope(vm_); GTEST_LOG_(INFO) << "sample_primitive_SymbolRef=================================================================="; Local symbolObject = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "description")); Local symbolDescription = symbolObject->GetDescription(vm_); GTEST_LOG_(INFO) << "sample_primitive_symbol_description : " << symbolDescription->ToString(vm_); Local psymbolObject = symbolObject; GTEST_LOG_(INFO) << "sample_primitive_SymbolRef_Psym_IsSymbol : " << psymbolObject->IsSymbol(vm_); } /* demo2 本地指针包装的使用。 */ class NativePointerTestClass { public: NativePointerTestClass() : someProperty(0) { GTEST_LOG_(INFO) << "NativePointerTestClass Construction"; } ~NativePointerTestClass() { GTEST_LOG_(INFO) << "NativePointerTestClass Destruction"; } int GetsomeProperty() const { return someProperty; } void SetsomeProperty(int value) { someProperty = value; } private: int someProperty; }; HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef) { LocalScope scope(vm_); NativePointerTestClass *nativePointerTestClass = new NativePointerTestClass(); GTEST_LOG_(INFO) << "sample_NativePointer adress: " << nativePointerTestClass; Local nativePoint = NativePointerRef::New( vm_, nativePointerTestClass, [](void *env, void *value, void *hint) { GTEST_LOG_(INFO) << "NativePointerCb value : " << value; GTEST_LOG_(INFO) << "NativePointerCb hint : " << hint; NativePointerTestClass *ptr = static_cast(value); delete ptr; }, (void *)0x123); NativePointerTestClass *yourClassPtr = static_cast(nativePoint->Value()); GTEST_LOG_(INFO) << "sample_NativePointer GetValue : " << yourClassPtr->GetsomeProperty(); yourClassPtr->SetsomeProperty(99); GTEST_LOG_(INFO) << "sample_NativePointer SetValue : " << yourClassPtr->GetsomeProperty(); GTEST_LOG_(INFO) << "sample_NativePointer Value : " << nativePoint->Value(); } HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_String) { LocalScope scope(vm_); void *vps = new std::string("123456"); Local nativePoint = NativePointerRef::New(vm_, vps); std::string *p = (std::string *)nativePoint->Value(); GTEST_LOG_(INFO) << "sample_NativePointerRef_String Value : " << *p; std::string value = "78910"; *p = value; GTEST_LOG_(INFO) << "sample_NativePointerRef_String ChangeValue : " << *((std::string *)nativePoint->Value()); } HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Double) { LocalScope scope(vm_); void *vpd = new double(123.456); Local nativePoint = NativePointerRef::New(vm_, vpd); double *p = (double *)nativePoint->Value(); GTEST_LOG_(INFO) << "sample_NativePointerRef_Double Value : " << *p; double value = 66.66; *p = value; GTEST_LOG_(INFO) << "sample_NativePointerRef_Double ChangeValue: " << *((double *)nativePoint->Value()); } HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Char) { LocalScope scope(vm_); void *vpc = new char('a'); Local nativePoint = NativePointerRef::New(vm_, vpc); char *p = (char *)nativePoint->Value(); GTEST_LOG_(INFO) << "sample_NativePointerRef_Char Value : " << *p; *p = 'A'; GTEST_LOG_(INFO) << "sample_NativePointerRef_Char ChangeValue: " << *((char *)nativePoint->Value()); } HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Long) { LocalScope scope(vm_); void *vpl = new long(123456); Local nativePoint = NativePointerRef::New(vm_, vpl); long *p = (long *)nativePoint->Value(); GTEST_LOG_(INFO) << "sample_NativePointerRef_Long Value : " << *p; long value = 2147483647; *p = value; GTEST_LOG_(INFO) << "sample_NativePointerRef_Long ChangeValue: " << *((long *)nativePoint->Value()); } HWTEST_F_L0(JSNApiSampleTest, sample_NativePointerRef_Int) { LocalScope scope(vm_); void *vpi = new int(123); Local nativePoint = NativePointerRef::New(vm_, vpi); int *p = (int *)nativePoint->Value(); GTEST_LOG_(INFO) << "sample_NativePointerRef_Int Value : " << *p; int value = 147483647; *p = value; GTEST_LOG_(INFO) << "sample_NativePointerRef_Int ChangeValue: " << *((int *)nativePoint->Value()); } /* demo3 对object的操作 */ static std::vector> GetSymbolRef(EcmaVM *vm) { GTEST_LOG_(INFO) << "GetSymbolRef"; static std::vector> value = { SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "symbolKey1")), SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "symbolKey2")), SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "symbolKey3")) }; return value; } Local Setter1(JsiRuntimeCallInfo *info) { GTEST_LOG_(INFO) << "Setter is running"; int cnt = 0; // 0 = first element EscapeLocalScope scope(info->GetVM()); Local arg = info->GetCallArgRef(0); Local value = info->GetThisRef(); Local obj = value->ToObject(info->GetVM()); if (value->IsNumber()) { double num = value->ToNumber(info->GetVM())->Value(); int max = 100; // 100 = maxValue int min = 0; // 0 = minValue if (num < min || num > max) { return JSValueRef::Undefined(info->GetVM()); } } obj->Set(info->GetVM(), GetSymbolRef(info->GetVM())[cnt], arg); return JSValueRef::Undefined(info->GetVM()); } Local Setter2(JsiRuntimeCallInfo *info) { GTEST_LOG_(INFO) << "Setter is running"; int cnt = 1; // 1 = second element EscapeLocalScope scope(info->GetVM()); Local arg = info->GetCallArgRef(0); Local value = info->GetThisRef(); Local obj = value->ToObject(info->GetVM()); if (!arg->IsString(info->GetVM())) { return JSValueRef::Undefined(info->GetVM()); } obj->Set(info->GetVM(), GetSymbolRef(info->GetVM())[cnt], arg); return JSValueRef::Undefined(info->GetVM()); } Local Setter3(JsiRuntimeCallInfo *info) { GTEST_LOG_(INFO) << "Setter is running"; int cnt = 2; // 2 = third element EscapeLocalScope scope(info->GetVM()); Local arg = info->GetCallArgRef(0); Local value = info->GetThisRef(); Local obj = value->ToObject(info->GetVM()); if (!arg->IsSymbol(info->GetVM())) { return JSValueRef::Undefined(info->GetVM()); } obj->Set(info->GetVM(), GetSymbolRef(info->GetVM())[cnt], arg); return JSValueRef::Undefined(info->GetVM()); } Local Getter1(JsiRuntimeCallInfo *info) { GTEST_LOG_(INFO) << "Getter is running"; int cnt = 0; // 0 = first element Local value = info->GetThisRef(); Local obj = value->ToObject(info->GetVM()); Local temp = obj->Get(info->GetVM(), GetSymbolRef(info->GetVM())[cnt]); return temp->ToString(info->GetVM()); } Local Getter2(JsiRuntimeCallInfo *info) { GTEST_LOG_(INFO) << "Getter is running"; int cnt = 1; // 1 = second element Local value = info->GetThisRef(); Local obj = value->ToObject(info->GetVM()); Local temp = obj->Get(info->GetVM(), GetSymbolRef(info->GetVM())[cnt]); return temp->ToString(info->GetVM()); } Local Getter3(JsiRuntimeCallInfo *info) { GTEST_LOG_(INFO) << "Getter is running"; int cnt = 2; // 2 = third element Local value = info->GetThisRef(); Local obj = value->ToObject(info->GetVM()); Local temp = obj->Get(info->GetVM(), GetSymbolRef(info->GetVM())[cnt]); if (!temp->IsSymbol(info->GetVM())) { JSValueRef::Undefined(info->GetVM()); } Local str = temp; return str->GetDescription(info->GetVM()); } void ObjectRefSet(Local object, EcmaVM *vm, Local symbol) { GTEST_LOG_(INFO) << "ObjectRefSet"; int cnt = 1; // 1 = key bool b = object->Set(vm, cnt, StringRef::NewFromUtf8(vm, "TestValue1")); ASSERT_TRUE(b); b = object->Set(vm, StringRef::NewFromUtf8(vm, "Test2"), StringRef::NewFromUtf8(vm, "TestValue2")); ASSERT_TRUE(b); b = object->Set(vm, StringRef::NewFromUtf8(vm, "Test3"), StringRef::NewFromUtf8(vm, "TestValue3")); ASSERT_TRUE(b); b = object->Set(vm, symbol, StringRef::NewFromUtf8(vm, "symbolValue")); ASSERT_TRUE(b); Local getter1 = FunctionRef::New(vm, Getter1); Local setter1 = FunctionRef::New(vm, Setter1); Local getter2 = FunctionRef::New(vm, Getter2); Local setter2 = FunctionRef::New(vm, Setter2); Local getter3 = FunctionRef::New(vm, Getter3); Local setter3 = FunctionRef::New(vm, Setter3); PropertyAttribute attribute1(StringRef::NewFromUtf8(vm, "AttributeValue1"), true, true, false); PropertyAttribute attribute2(StringRef::NewFromUtf8(vm, "AttributeValue2"), false, true, true); PropertyAttribute attribute3(StringRef::NewFromUtf8(vm, "AttributeValue3"), true, false, true); attribute1.SetGetter(getter1); attribute1.SetSetter(setter1); b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"), attribute1); ASSERT_TRUE(b); b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "Test2"), attribute2); ASSERT_TRUE(b); b = object->SetAccessorProperty(vm, StringRef::NewFromUtf8(vm, "Accessor1"), getter1, setter1); ASSERT_TRUE(b); b = object->SetAccessorProperty(vm, StringRef::NewFromUtf8(vm, "Test3"), getter2, setter2); ASSERT_TRUE(b); b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"), attribute3); ASSERT_TRUE(b); b = object->SetAccessorProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"), getter3, setter3, attribute3); ASSERT_TRUE(b); } void GetProperty(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "GetProperty"; Local names = object->GetOwnPropertyNames(vm); int cnt = names->Length(vm); GTEST_LOG_(INFO) << "GetOwnPropertyNames cnt: " << cnt; for (int i = 0; i < cnt; i++) { Local value = ArrayRef::GetValueAt(vm, names, i); if (value->IsSymbol(vm)) { Local symbol = value; GTEST_LOG_(INFO) << "PropertyNames: " << symbol->GetDescription(vm)->ToString(vm); } else { GTEST_LOG_(INFO) << "PropertyNames: " << value->ToString(vm)->ToString(vm); } } } void Get(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "Get"; int cnt = 1; // 1 = key Local value = object->Get(vm, cnt); if (value->IsString(vm)) { GTEST_LOG_(INFO) << "Key:1 Value:" << value->ToString(vm)->ToString(vm); } value = object->Get(vm, StringRef::NewFromUtf8(vm, "Test2")); if (value->IsString(vm)) { GTEST_LOG_(INFO) << "Key:Test2 Value:" << value->ToString(vm)->ToString(vm); } value = object->Get(vm, StringRef::NewFromUtf8(vm, "AttributeKey1")); if (value->IsString(vm)) { GTEST_LOG_(INFO) << "Key:AttributeKey1 Value:" << value->ToString(vm)->ToString(vm); } int num = 10; // 10 = randomness object->Set(vm, StringRef::NewFromUtf8(vm, "Accessor1"), NumberRef::New(vm, num)); object->Set(vm, StringRef::NewFromUtf8(vm, "Test3"), StringRef::NewFromUtf8(vm, "Test3Value")); object->Set(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"), SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "AttributeKey3Value"))); Local str = object->Get(vm, StringRef::NewFromUtf8(vm, "AttributeKey3")); if (str->IsString(vm)) { GTEST_LOG_(INFO) << "Key:AttributeKey3 Value:" << str->ToString(vm); } str = object->Get(vm, StringRef::NewFromUtf8(vm, "Accessor1")); if (str->IsString(vm)) { GTEST_LOG_(INFO) << "Key:Accessor1 Value:" << str->ToString(vm); } str = object->Get(vm, StringRef::NewFromUtf8(vm, "Test3")); if (str->IsString(vm)) { GTEST_LOG_(INFO) << "Key:Test3 Value:" << str->ToString(vm); } } void SetValueAgain(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "SetValueAgain"; GTEST_LOG_(INFO) << "SetValueAgain"; int cnt = 1; // 1 = key bool b = object->Set(vm, cnt, StringRef::NewFromUtf8(vm, "TestValueAgain1")); ASSERT_TRUE(b); b = object->Set(vm, StringRef::NewFromUtf8(vm, "Test3"), StringRef::NewFromUtf8(vm, "TestValueAgain3")); ASSERT_TRUE(b); b = object->Set(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"), StringRef::NewFromUtf8(vm, "AttributeValueAgain1")); ASSERT_TRUE(b); b = object->Set(vm, StringRef::NewFromUtf8(vm, "AttributeKey3"), StringRef::NewFromUtf8(vm, "AttributeValueAgain3")); ASSERT_TRUE(b); b = object->Set(vm, StringRef::NewFromUtf8(vm, "Accessor1"), StringRef::NewFromUtf8(vm, "AttributeValueAgain2")); ASSERT_TRUE(b); GTEST_LOG_(INFO) << "GetValueAgain"; Get(object, vm); GetProperty(object, vm); } void GetOwnEnumerablePropertyNames(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "GetOwnEnumerablePropertyNames"; Local names = object->GetOwnEnumerablePropertyNames(vm); int cnt = names->Length(vm); GTEST_LOG_(INFO) << "GetOwnEnumerablePropertyNames cnt: " << cnt; for (int i = 0; i < cnt; i++) { Local value = ArrayRef::GetValueAt(vm, names, i); if (value->IsSymbol(vm)) { Local symbol = value; GTEST_LOG_(INFO) << "PropertyNames: " << symbol->GetDescription(vm)->ToString(vm); } else { GTEST_LOG_(INFO) << "PropertyNames: " << value->ToString(vm)->ToString(vm); } } } void PrintAllProperty(Local object, EcmaVM *vm, int flag) { Local names = object->GetAllPropertyNames(vm, flag); int cnt = names->Length(vm); switch (flag) { case 0: // 0 = NATIVE_DEFAULT GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_DEFAULT: " << cnt; break; case 1: // 1 = NATIVE_WRITABLE GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_WRITABLE: " << cnt; break; case 2: // 2 = NATIVE_ENUMERABLE GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_ENUMERABLE: " << cnt; break; case 3: // 3 = NATIVE_CONFIGURABLE GTEST_LOG_(INFO) << "GetOwnPropertyNames NATIVE_CONFIGURABLE: " << cnt; break; default: break; } for (int i = 0; i < cnt; i++) { Local value = ArrayRef::GetValueAt(vm, names, i); if (value->IsSymbol(vm)) { Local symbol = value; GTEST_LOG_(INFO) << "PropertyNames: " << symbol->GetDescription(vm)->ToString(vm); } else { GTEST_LOG_(INFO) << "PropertyNames: " << value->ToString(vm)->ToString(vm); } } } void GetAllPropertyNames(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "GetAllPropertyNames"; for (int i = 0; i < 4; i++) { // 4 show Go through all the properties PrintAllProperty(object, vm, i); } } void HasAndDelete(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "HasAndDelete"; bool b = object->Has(vm, 1); // 1 = key ASSERT_TRUE(b); b = object->Has(vm, StringRef::NewFromUtf8(vm, "Test2")); ASSERT_TRUE(b); b = object->Delete(vm, StringRef::NewFromUtf8(vm, "Test2")); ASSERT_TRUE(b); b = object->Has(vm, StringRef::NewFromUtf8(vm, "Test2")); ASSERT_FALSE(b); } void FreezeAndSeal(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "FreezeAndSeal"; object->Seal(vm); int num1 = 1; // 1 = key int num2 = 2; // 2 = key bool b = object->Set(vm, num1, StringRef::NewFromUtf8(vm, "Seal1")); ASSERT_TRUE(b); b = object->Delete(vm, num1); ASSERT_FALSE(b); b = object->Set(vm, num2, StringRef::NewFromUtf8(vm, "2")); ASSERT_FALSE(b); object->Freeze(vm); PropertyAttribute attribute(StringRef::NewFromUtf8(vm, "FreezeValue"), true, true, false); b = object->DefineProperty(vm, StringRef::NewFromUtf8(vm, "Freeze"), attribute); ASSERT_FALSE(b); b = object->Has(vm, num2); ASSERT_FALSE(b); b = object->Has(vm, StringRef::NewFromUtf8(vm, "Freeze")); ASSERT_FALSE(b); b = object->Delete(vm, num2); ASSERT_FALSE(b); b = object->Delete(vm, StringRef::NewFromUtf8(vm, "Freeze")); ASSERT_FALSE(b); } void GetOwnProperty(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "GetOwnProperty"; PropertyAttribute value1; bool b = object->GetOwnProperty(vm, NumberRef::New(vm, 1), value1); ASSERT_TRUE(b); PropertyAttribute value2; b = object->GetOwnProperty(vm, StringRef::NewFromUtf8(vm, "AttributeKey1"), value2); ASSERT_TRUE(b); ASSERT_EQ(true, value2.IsWritable()); ASSERT_EQ(true, value2.IsEnumerable()); ASSERT_EQ(false, value2.IsConfigurable()); ASSERT_EQ(true, value2.HasWritable()); ASSERT_EQ(true, value2.HasConfigurable()); ASSERT_EQ(true, value2.HasEnumerable()); Local value = value2.GetValue(vm); ASSERT_EQ("AttributeValue1", value->ToString(vm)->ToString(vm)); } class A { public: void Test() const { GTEST_LOG_(INFO) << "Class A Test()"; } }; void NativePointer(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "NativePointer"; int cnt = 10; // 10 = accommodate quantity object->SetNativePointerFieldCount(vm, cnt); ASSERT_EQ(cnt, object->GetNativePointerFieldCount(vm)); A *a = new A(); int cnt2 = 1; // 11 = random Numbers int cnt3 = 11; // 1 = random Numbers object->SetNativePointerField(vm, cnt2, static_cast(a), nullptr, nullptr); object->SetNativePointerField(vm, cnt3, static_cast(a), nullptr, nullptr); A *value1 = static_cast(object->GetNativePointerField(vm, cnt2)); A *value2 = static_cast(object->GetNativePointerField(vm, cnt3)); if (value1 == nullptr) { GTEST_LOG_(INFO) << "SetNativePointerField is Error"; } else { value1->Test(); } if (value2 == nullptr) { GTEST_LOG_(INFO) << "SetNativePointerField is OK"; } Local native = NativePointerRef::New(vm, static_cast(a)); bool b = object->ConvertToNativeBindingObject(vm, native); ASSERT_TRUE(b); } void SetPrototype(Local object, EcmaVM *vm) { GTEST_LOG_(INFO) << "SetPrototype"; int cnt = 111; // 111 = random Numbers Local obj = NumberRef::New(vm, cnt); object->SetPrototype(vm, obj); Local type = object->GetPrototype(vm); if (type->IsUndefined() || type->IsNull()) { return; } GTEST_LOG_(INFO) << "Prototype: " << type->Typeof(vm)->ToString(vm); } HWTEST_F_L0(JSNApiSampleTest, Sample_Demo3_ObjectRef) { GTEST_LOG_(INFO) << "SetPrototype"; LocalScope scope(vm_); GetSymbolRef(vm_); Local symbol = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "Symbol")); Local object = ObjectRef::New(vm_); SetPrototype(object, vm_); ObjectRefSet(object, vm_, symbol); GetProperty(object, vm_); GetOwnProperty(object, vm_); GetAllPropertyNames(object, vm_); GetOwnEnumerablePropertyNames(object, vm_); Get(object, vm_); NativePointer(object, vm_); SetValueAgain(object, vm_); HasAndDelete(object, vm_); FreezeAndSeal(object, vm_); } /* demo4 无参无返回值的函数的调用。 ts: * function FuncTest(): void { * console.log("func test log ..."); * } * FuncTest(); */ HWTEST_F_L0(JSNApiSampleTest, sample_demo4_function_test_1) { GTEST_LOG_(INFO) << "sample_demo4_function_test_1 ======================================="; LocalScope scope(vm_); Local FuncTest = FunctionRef::New(vm_, [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); GTEST_LOG_(INFO) << "func test log ..."; return JSValueRef::Undefined(vm); }); FuncTest->Call(vm_, JSValueRef::Undefined(vm_), nullptr, 0); GTEST_LOG_(INFO) << "sample_demo4_function_test_1 =========================================="; } /* demo4 有参有返回值的函数的调用。 ts: * function Add(x: number, y: number): number { * return x + y; * } * let sum = Add(12, 34); * console.log(sum); */ HWTEST_F_L0(JSNApiSampleTest, sample_demo4_function_test_2) { GTEST_LOG_(INFO) << "sample_demo4_function_test_2 ======================================="; LocalScope scope(vm_); Local Add = FunctionRef::New(vm_, [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 参数的个数。 uint32_t argsCount = runtimeInfo->GetArgsNumber(); // 遍历参数。 for (uint32_t i = 0; i < argsCount; ++i) { Local arg = runtimeInfo->GetCallArgRef(i); GTEST_LOG_(INFO) << "func test arg " << i << " " << arg->Int32Value(vm); } // 获取前两个参数。 Local jsArg0 = runtimeInfo->GetCallArgRef(0); Local jsArg1 = runtimeInfo->GetCallArgRef(1); int arg0 = jsArg0->Int32Value(vm); int arg1 = jsArg1->Int32Value(vm); int sum = arg0 + arg1; GTEST_LOG_(INFO) << "func test sum " << sum; // 参数返回值 return NumberRef::New(vm, sum); }); int argv0 = 12; // random number int argv1 = 34; // random number Local *argv = new Local[2]; argv[0] = NumberRef::New(vm_, argv0); argv[1] = NumberRef::New(vm_, argv1); Local jsSum = Add->Call(vm_, JSValueRef::Undefined(vm_), argv, 2); int sum = jsSum->Int32Value(vm_); GTEST_LOG_(INFO) << "func test call sum " << sum; GTEST_LOG_(INFO) << "sample_demo4_function_test_2 =========================================="; } Local AddFunc(JsiRuntimeCallInfo *runtimeInfo) { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 参数的个数。 uint32_t argsCount = runtimeInfo->GetArgsNumber(); // 遍历参数。 for (uint32_t i = 0; i < argsCount; ++i) { Local arg = runtimeInfo->GetCallArgRef(i); GTEST_LOG_(INFO) << "func test arg " << i << " " << arg->Int32Value(vm); } // 获取前两个参数。 Local jsArg0 = runtimeInfo->GetCallArgRef(0); Local jsArg1 = runtimeInfo->GetCallArgRef(1); int arg0 = jsArg0->Int32Value(vm); int arg1 = jsArg1->Int32Value(vm); int sum = arg0 + arg1; // 参数返回值 return NumberRef::New(vm, sum); } Local AddProxyFunc(JsiRuntimeCallInfo *runtimeInfo) { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 参数的个数。 uint32_t argsCount = runtimeInfo->GetArgsNumber(); // 函数调用的时候的传参个数,如果不能等于这个值说明函数调用有问题。 uint32_t defaultArgsCount = 3; if (argsCount != defaultArgsCount) { return NumberRef::New(vm, 0); } // 函数 int index = 0; // 获取参数的索引。 Local jsArg0 = runtimeInfo->GetCallArgRef(index); // 获取前两个参数。 index++; Local jsArg1 = runtimeInfo->GetCallArgRef(index); index++; Local jsArg2 = runtimeInfo->GetCallArgRef(index); Local addFunc = jsArg0; const int addFuncArgCount = 2; // 内部调用的函数的参数个数。 Local argv[addFuncArgCount] = { jsArg1, jsArg2 }; Local jsSum = addFunc->Call(vm, JSValueRef::Undefined(vm), argv, addFuncArgCount); int sum = jsSum->Int32Value(vm); int multiple = 2; // 代理的功能,原函数的2倍返回。 sum *= multiple; // 参数返回值 return NumberRef::New(vm, sum); } /* demo4 参数是函数的调用。 ts: * function Add(x: number, y: number): number { * return x + y; * } * function AddProxy(add: (x: number, y: number) => number, x: number, y: number) { * let sum = add(x, y); * return sum * 2 * } * let sum1 = Add(12, 34); * let sum2 = AddProxy(Add,12, 34); * console.log(sum1); * console.log(sum2); */ HWTEST_F_L0(JSNApiSampleTest, sample_demo4_function_test_3) { GTEST_LOG_(INFO) << "sample_demo4_function_test_3 ======================================="; LocalScope scope(vm_); Local Add = FunctionRef::New(vm_, AddFunc); Local AddProxy = FunctionRef::New(vm_, AddProxyFunc); int num1 = 12; // random number int num2 = 34; // random number Local addArgv[2]; addArgv[0] = NumberRef::New(vm_, num1); addArgv[1] = NumberRef::New(vm_, num2); Local addProxyArgv[3]; addProxyArgv[0] = Add; addProxyArgv[1] = NumberRef::New(vm_, num1); addProxyArgv[2] = NumberRef::New(vm_, num2); Local jsSum1 = Add->Call(vm_, JSValueRef::Undefined(vm_), addArgv, 2); Local jsSum2 = AddProxy->Call(vm_, JSValueRef::Undefined(vm_), addProxyArgv, 3); int sum1 = jsSum1->Int32Value(vm_); int sum2 = jsSum2->Int32Value(vm_); GTEST_LOG_(INFO) << "func test call Add , sum = " << sum1; GTEST_LOG_(INFO) << "func test call AddProxy , sum = " << sum2; GTEST_LOG_(INFO) << "sample_demo4_function_test_3 =========================================="; } /* demo5 类的静态函数和非静态函数的测试,静态变量变量 和 非静态变量的测试。 ts: * class Greeter { * // 静态变量。 * static position:string = "door"; * // 私有静态变量。 * private static standardGreetingStr:string = "Hello, there"; * * // 私有非静态变量。 * private privateGreeting: string; * // 非静态变量。 * greeting: string; * * // 构造函数。 * constructor(greet: string) { * this.greeting = greet; * } * * // 非静态函数。 * SetPrivateGreeting(priGreeting: string):void * { * this.privateGreeting = priGreeting; * } * * // 非静态函数调用。 * Greet(): string { * if (this.privateGreeting) { * return "Hello, " + this.privateGreeting; * }else if (this.greeting) { * return "Hello, " + this.greeting; * } * else { * return Greeter.standardGreetingStr; * } * } * * // 静态函数调用。 * static StandardGreeting(): string { * return Greeter.standardGreetingStr; * } * * // 静态函数调用。 * static StandardPosition(): string { * return Greeter.position; * } * * } * * let greeter1: Greeter = new Greeter("everyone"); * * // 非静态函数调用 * console.log(greeter1.Greet()); * * greeter1.SetPrivateGreeting("vip"); * console.log(greeter1.Greet()); * * greeter1.SetPrivateGreeting(""); * console.log(greeter1.Greet()); * * // 修改变量 * greeter1.greeting = ""; * console.log(greeter1.Greet()); * * // 静态函数调用。 * console.log(Greeter.StandardGreeting()); * console.log(Greeter.StandardPosition()); * * // 修改静态变量。 * Greeter.position = "house"; * console.log(Greeter.StandardPosition()); */ class Tag { public: explicit Tag(const std::string name) : name_(name) { GTEST_LOG_(INFO) << "tag construction , name is " << name_; } ~Tag() { GTEST_LOG_(INFO) << "tag deconstruction , name is " << name_; } private: std::string name_; }; class Greeter { private: // 新建ClassFunction static Local NewClassFunction(EcmaVM *vm); // 添加静态变量。 static void AddStaticVariable(EcmaVM *vm, Local &claFunc); // 添加静态函数。 static void AddStaticFunction(EcmaVM *vm, Local &claFunc); // 添加非静态变量。 static void AddVariable(EcmaVM *vm, Local &proto); // 添加非静态函数。 static void AddFunction(EcmaVM *vm, Local &proto); public: // 获取ClassFunction static Local GetClassFunction(EcmaVM *vm); static Local New(EcmaVM *vm, Local greet); // 非静态函数调用。 static void SetPrivateGreeting(EcmaVM *vm, Local thisRef, Local priGreeting); static Local Greet(EcmaVM *vm, Local thisRef); // 静态函数的调用。 static Local StandardGreeting(EcmaVM *vm); static Local StandardPosition(EcmaVM *vm); private: static Local standardGreetingStrKey; static Local privateGreetingKey; // 类名 const static std::string CLASS_NAME; }; Local Greeter::standardGreetingStrKey; Local Greeter::privateGreetingKey; const std::string Greeter::CLASS_NAME = "GreeterClass"; Local Greeter::NewClassFunction(EcmaVM *vm) { // 初始化私有静态变量的key。 Greeter::standardGreetingStrKey = SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "standardGreetingStr")); Greeter::privateGreetingKey = SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "privateGreeting")); Tag *tag = new Tag("ClassFunctionTag"); Local claFunc = FunctionRef::NewClassFunction( vm, // 构造函数调用 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); // 获取参数。 Local greet = runtimeInfo->GetCallArgRef(0); // ts: this.greeting = greet; thisRef->Set(vm, StringRef::NewFromUtf8(vm, "greeting"), greet); return thisRef; }, [](void *env, void *nativePointer, void *data) { GTEST_LOG_(INFO) << "NewClassFunction, nativePointer is " << nativePointer; Tag *t = static_cast(data); delete t; }, tag); // static 添加 到 claFunc。 // 添加静态变量。 AddStaticVariable(vm, claFunc); // 添加静态函数 AddStaticFunction(vm, claFunc); Local jsProto = claFunc->GetFunctionPrototype(vm); Local proto = jsProto->ToObject(vm); // 非static 添加到 proto。 // 添加非静态变量 AddVariable(vm, proto); // 添加非静态函数 AddFunction(vm, proto); // 设置类名。 claFunc->SetName(vm, StringRef::NewFromUtf8(vm, Greeter::CLASS_NAME.c_str())); return claFunc; } Local Greeter::GetClassFunction(EcmaVM *vm) { Local globalObj = JSNApi::GetGlobalObject(vm); Local jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, Greeter::CLASS_NAME.c_str())); if (jsClaFunc->IsFunction(vm)) { return jsClaFunc; } Local claFunc = Greeter::NewClassFunction(vm); // 添加到全局。 globalObj->Set(vm, claFunc->GetName(vm), claFunc); return claFunc; } // 添加静态变量。 void Greeter::AddStaticVariable(EcmaVM *vm, Local &claFunc) { // 静态变量。 // static position:string = "door"; claFunc->Set(vm, StringRef::NewFromUtf8(vm, "position"), StringRef::NewFromUtf8(vm, "door")); // 私有静态变量。 // private static standardGreetingStr:string = "Hello, there"; claFunc->Set(vm, Greeter::standardGreetingStrKey, StringRef::NewFromUtf8(vm, "Hello, there")); } // 添加静态函数。 void Greeter::AddStaticFunction(EcmaVM *vm, Local &claFunc) { // 静态函数调用。 claFunc->Set(vm, StringRef::NewFromUtf8(vm, "StandardGreeting"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); Local claFunc = Greeter::GetClassFunction(vm); Local jsStandardGreetingStr = claFunc->Get(vm, Greeter::standardGreetingStrKey); return jsStandardGreetingStr; })); // 静态函数调用。 claFunc->Set(vm, StringRef::NewFromUtf8(vm, "StandardPosition"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); Local claFunc = Greeter::GetClassFunction(vm); Local jsPosition = claFunc->Get(vm, StringRef::NewFromUtf8(vm, "position")); return jsPosition; })); } // 添加非静态变量。 void Greeter::AddVariable(EcmaVM *vm, Local &proto) { // 私有非静态变量。 proto->Set(vm, Greeter::privateGreetingKey, JSValueRef::Undefined(vm)); // 非静态变量。 proto->Set(vm, StringRef::NewFromUtf8(vm, "greeting"), JSValueRef::Undefined(vm)); } // 添加非静态函数。 void Greeter::AddFunction(EcmaVM *vm, Local &proto) { // 非静态函数。 proto->Set(vm, StringRef::NewFromUtf8(vm, "SetPrivateGreeting"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); // 获取参数。 Local priGreeting = runtimeInfo->GetCallArgRef(0); thisRef->Set(vm, Greeter::privateGreetingKey, priGreeting); return JSValueRef::Undefined(vm); })); // 非静态函数。 proto->Set(vm, StringRef::NewFromUtf8(vm, "Greet"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取类 Local claFunc = Greeter::GetClassFunction(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); Local jsPrivateGreeting = thisRef->Get(vm, Greeter::privateGreetingKey); Local jsGreeting = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "greeting")); Local jsStandardGreetingStr = claFunc->Get(vm, Greeter::standardGreetingStrKey); std::string ret; if (jsPrivateGreeting->IsString(vm)) { ret.append("Hello, ").append(jsPrivateGreeting->ToString(vm)->ToString(vm)); } else if (jsGreeting->IsString(vm)) { ret.append("Hello, ").append(jsGreeting->ToString(vm)->ToString(vm)); } else { ret.append(jsStandardGreetingStr->ToString(vm)->ToString(vm)); } return StringRef::NewFromUtf8(vm, ret.c_str(), ret.size()); })); } Local Greeter::New(EcmaVM *vm, Local greet) { // 获取类函数。 Local claFunc = Greeter::GetClassFunction(vm); // 定义参数。 Local argv[1] = {greet}; // 构造函数,构造对象。 Local jsObj = claFunc->Constructor(vm, argv, 1); Local obj = jsObj->ToObject(vm); return obj; } /* // 非静态函数调用。 ts: * SetPrivateGreeting(priGreeting: string):void */ void Greeter::SetPrivateGreeting(EcmaVM *vm, Local thisRef, Local priGreeting) { Local objRef = thisRef; Local func = objRef->Get(vm, StringRef::NewFromUtf8(vm, "SetPrivateGreeting")); Local argv [1] = {priGreeting}; func->Call(vm, objRef, argv, 1); } /* // 非静态函数调用。 ts: * Greet(): string */ Local Greeter::Greet(EcmaVM *vm, Local thisRef) { Local objRef = thisRef; Local func = objRef->Get(vm, StringRef::NewFromUtf8(vm, "Greet")); return func->Call(vm, objRef, nullptr, 0); } /* // 静态函数的调用。 ts: * static StandardGreeting(): string */ Local Greeter::StandardGreeting(EcmaVM *vm) { // 获取类函数。 Local claFunc = Greeter::GetClassFunction(vm); // 获取函数 Local func = claFunc->Get(vm, StringRef::NewFromUtf8(vm, "StandardGreeting")); // 调用函数 return func->Call(vm, JSValueRef::Undefined(vm), nullptr, 0); } /* // 静态函数的调用。ts: * static StandardPosition(): string */ Local Greeter::StandardPosition(EcmaVM *vm) { // 获取类函数。 Local claFunc = Greeter::GetClassFunction(vm); // 获取函数 Local func = claFunc->Get(vm, StringRef::NewFromUtf8(vm, "StandardPosition")); // 调用函数 return func->Call(vm, JSValueRef::Undefined(vm), nullptr, 0); } /* 类的调用测试: ts: * let greeter1: Greeter = new Greeter("everyone"); * * // 非静态函数调用 * console.log(greeter1.Greet()); * * greeter1.SetPrivateGreeting("vip"); * console.log(greeter1.Greet()); * * greeter1.SetPrivateGreeting(""); * console.log(greeter1.Greet()); * * // 修改变量 * greeter1.greeting = ""; * console.log(greeter1.Greet()); * * // 静态函数调用。 * console.log(Greeter.StandardGreeting()); * console.log(Greeter.StandardPosition()); * * // 修改静态变量。 * Greeter.position = "house"; * console.log(Greeter.StandardPosition()); */ HWTEST_F_L0(JSNApiSampleTest, sample_demo5_class_test) { GTEST_LOG_(INFO) << "sample_demo5_class_test ======================================="; LocalScope scope(vm_); Local greeter1 = Greeter::New(vm_, StringRef::NewFromUtf8(vm_, "everyone")); // 非静态函数调用 GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_); Greeter::SetPrivateGreeting(vm_, greeter1, StringRef::NewFromUtf8(vm_, "vip")); GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_); Greeter::SetPrivateGreeting(vm_, greeter1, JSValueRef::Undefined(vm_)); GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_); // 修改变量 Local objRef1 = greeter1; objRef1->Set(vm_, StringRef::NewFromUtf8(vm_, "greeting"), JSValueRef::Undefined(vm_)); GTEST_LOG_(INFO) << Greeter::Greet(vm_, greeter1)->ToString(vm_); // 静态函数调用。 GTEST_LOG_(INFO) << Greeter::StandardGreeting(vm_)->ToString(vm_); GTEST_LOG_(INFO) << Greeter::StandardPosition(vm_)->ToString(vm_); // 修改静态变量。 Local classFunc = Greeter::GetClassFunction(vm_); classFunc->Set(vm_, StringRef::NewFromUtf8(vm_, "position"), StringRef::NewFromUtf8(vm_, "house")); GTEST_LOG_(INFO) << Greeter::StandardPosition(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "sample_demo5_class_test ======================================="; } /* demo6 多态 ts: * // 基类 * class Derive { * baseNum: number = 1 * constructor(num: number){ * this.baseNum = num * } * Compute(): number { * return this.baseNum * } * } * // 子类1 * class DeriveDouble extends Derive { * constructor(num: number){ * super(num); * } * Compute() : number { * return this.baseNum * 2 * } * } * // 子类2 * class DerivedTriple extends Derive { * constructor(num: number){ * super(num); * } * Compute() : number { * return this.baseNum * 3 * } * } * * // 测试: * let d1: Derive; * let d2: Derive; * let d3: Derive; * d1 = new Derive(5);//新建基类。 * d2 = new DeriveDouble(5);//新建子类。 * d3 = new DerivedTriple(5);//新建子类。 * let i1:number = d1.Compute(); * let i2:number = d2.Compute(); * let i3:number = d3.Compute(); * console.log(i1); * console.log(i2); * console.log(i3); */ /* 基类 ts: * class Derive { * baseNum: number = 1 * constructor(num: number){ * this.baseNum = num * } * Compute(): number { * return this.baseNum * } * } */ class Derive { private: // 新建ClassFunction static Local NewClassFunction(EcmaVM *vm); public: // 获取ClassFunction static Local GetClassFunction(EcmaVM *vm); static Local New(EcmaVM *vm, Local num); static Local Compute(EcmaVM *vm, Local thisRef); private: const static std::string CLASS_NAME; }; const std::string Derive::CLASS_NAME = "DeriveClass"; Local Derive::NewClassFunction(EcmaVM *vm) { Local claFunc = FunctionRef::NewClassFunction( vm, // 构造函数调用 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); // 获取参数。 Local num = runtimeInfo->GetCallArgRef(0); // this.baseNum = num thisRef->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), num); return thisRef; }, nullptr, nullptr); Local jsProto = claFunc->GetFunctionPrototype(vm); Local proto = jsProto->ToObject(vm); // 添加非静态变量 proto->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), NumberRef::New(vm, 1)); // 添加非静态函数 proto->Set(vm, StringRef::NewFromUtf8(vm, "Compute"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); Local jsNum = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "baseNum")); int num = jsNum->Int32Value(vm); return NumberRef::New(vm, num); })); // 设置类名。 claFunc->SetName(vm, StringRef::NewFromUtf8(vm, Derive::CLASS_NAME.c_str())); return claFunc; } Local Derive::GetClassFunction(EcmaVM *vm) { Local globalObj = JSNApi::GetGlobalObject(vm); Local jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, Derive::CLASS_NAME.c_str())); if (jsClaFunc->IsFunction(vm)) { return jsClaFunc; } Local claFunc = Derive::NewClassFunction(vm); // 添加到全局。 globalObj->Set(vm, claFunc->GetName(vm), claFunc); return claFunc; } Local Derive::New(EcmaVM *vm, Local num) { // 获取类函数。 Local claFunc = Derive::GetClassFunction(vm); // 定义参数。 Local argv[1] = {num}; // 构造函数,构造对象。 Local jsObj = claFunc->Constructor(vm, argv, 1); Local obj = jsObj->ToObject(vm); return obj; } Local Derive::Compute(EcmaVM *vm, Local thisRef) { Local objRef = thisRef; Local func = objRef->Get(vm, StringRef::NewFromUtf8(vm, "Compute")); return func->Call(vm, objRef, nullptr, 0); } /* 子类1 ts: * class DeriveDouble extends Base { * constructor(num: number){ * super(num); * } * Compute() : number { * return this.baseNum * 2 * } * } */ class DeriveDouble : public Derive { private: DeriveDouble() = default; // 新建ClassFunction static Local NewClassFunction(EcmaVM *vm); public: // 获取ClassFunction static Local GetClassFunction(EcmaVM *vm); static Local New(EcmaVM *vm, Local num); ~DeriveDouble() = default; public: // 设置类名 const static std::string CLASS_NAME; }; const std::string DeriveDouble::CLASS_NAME = "DeriveDoubleClass"; Local DeriveDouble::NewClassFunction(EcmaVM *vm) { Local claFunc = FunctionRef::NewClassFunction( vm, // 构造函数调用 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取参数。 Local num = runtimeInfo->GetCallArgRef(0); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); // 修改父类。 thisRef->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), num); return thisRef; }, nullptr, nullptr); // 设置类名。 claFunc->SetName(vm, StringRef::NewFromUtf8(vm, DeriveDouble::CLASS_NAME.c_str())); // 添加非静态函数 Local proto = claFunc->GetFunctionPrototype(vm)->ToObject(vm); proto->Set(vm, StringRef::NewFromUtf8(vm, "Compute"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); Local jsNum = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "baseNum")); int num = jsNum->Int32Value(vm); int multiple = 2; // 函数功能,2倍返回。 num *= multiple; return NumberRef::New(vm, num); })); // 父类。 Local claFuncBase = Derive::GetClassFunction(vm); // 继承。 claFunc->Inherit(vm, claFuncBase); return claFunc; } Local DeriveDouble::GetClassFunction(EcmaVM *vm) { Local globalObj = JSNApi::GetGlobalObject(vm); Local jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, DeriveDouble::CLASS_NAME.c_str())); if (jsClaFunc->IsFunction(vm)) { return jsClaFunc; } Local claFunc = DeriveDouble::NewClassFunction(vm); globalObj->Set(vm, claFunc->GetName(vm), claFunc); return claFunc; } Local DeriveDouble::New(EcmaVM *vm, Local num) { // 获取类函数。 Local claFunc = DeriveDouble::GetClassFunction(vm); // 定义参数。 Local argv[1] = {num}; // 构造函数,构造对象。 Local jsObj = claFunc->Constructor(vm, argv, 1); Local obj = jsObj->ToObject(vm); return obj; } /* 子类2 ts: * class DerivedTriple extends Derive { * constructor(num: number){ * super(num); * } * Compute() : number { * return this.baseNum * 3 * } * } */ class DerivedTriple : public Derive { private: DerivedTriple() = default; // 新建ClassFunction static Local NewClassFunction(EcmaVM *vm); public: // 获取ClassFunction static Local GetClassFunction(EcmaVM *vm); static Local New(EcmaVM *vm, Local num); ~DerivedTriple() = default; public: // 设置类名 const static std::string CLASS_NAME; }; const std::string DerivedTriple::CLASS_NAME = "DerivedTripleClass"; Local DerivedTriple::NewClassFunction(EcmaVM *vm) { Local claFunc = FunctionRef::NewClassFunction( vm, // 构造函数调用 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取参数。 Local num = runtimeInfo->GetCallArgRef(0); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); // 修改父类。 thisRef->Set(vm, StringRef::NewFromUtf8(vm, "baseNum"), num); return thisRef; }, nullptr, nullptr); // 设置类名。 claFunc->SetName(vm, StringRef::NewFromUtf8(vm, DerivedTriple::CLASS_NAME.c_str())); // 添加非静态函数 Local proto = claFunc->GetFunctionPrototype(vm)->ToObject(vm); proto->Set(vm, StringRef::NewFromUtf8(vm, "Compute"), FunctionRef::New(vm, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // 获取this Local jsThisRef = runtimeInfo->GetThisRef(); Local thisRef = jsThisRef->ToObject(vm); Local jsNum = thisRef->Get(vm, StringRef::NewFromUtf8(vm, "baseNum")); int num = jsNum->Int32Value(vm); int multiple = 3; // 函数功能,3倍返回。 num *= multiple; return NumberRef::New(vm, num); })); // 父类。 Local claFuncBase = Derive::GetClassFunction(vm); // 继承。 claFunc->Inherit(vm, claFuncBase); return claFunc; } Local DerivedTriple::GetClassFunction(EcmaVM *vm) { Local globalObj = JSNApi::GetGlobalObject(vm); Local jsClaFunc = globalObj->Get(vm, StringRef::NewFromUtf8(vm, DerivedTriple::CLASS_NAME.c_str())); if (jsClaFunc->IsFunction(vm)) { return jsClaFunc; } Local claFunc = DerivedTriple::NewClassFunction(vm); globalObj->Set(vm, claFunc->GetName(vm), claFunc); return claFunc; } Local DerivedTriple::New(EcmaVM *vm, Local num) { // 获取类函数。 Local claFunc = DerivedTriple::GetClassFunction(vm); // 定义参数。 Local argv[1] = {num}; // 构造函数,构造对象。 Local jsObj = claFunc->Constructor(vm, argv, 1); Local obj = jsObj->ToObject(vm); return obj; } /* 测试。ts: * let d1: Derive; * let d2: Derive; * let d3: Derive; * d1 = new Derive(5);//新建基类。 * d2 = new DeriveDouble(5);//新建子类。 * d3 = new DerivedTriple(5);//新建子类。 * let i1:number = d1.Compute(); * let i2:number = d2.Compute(); * let i3:number = d3.Compute(); * console.log(i1); * console.log(i2); * console.log(i3); */ HWTEST_F_L0(JSNApiSampleTest, sample_demo6_polymorphic_test) { GTEST_LOG_(INFO) << "sample_demo6_polymorphic_test ======================================="; LocalScope scope(vm_); int num = 5; Local d1 = Derive::New(vm_, NumberRef::New(vm_, num)); Local d2 = DeriveDouble::New(vm_, NumberRef::New(vm_, num)); Local d3 = DerivedTriple::New(vm_, NumberRef::New(vm_, num)); Local i1 = Derive::Compute(vm_, d1); Local i2 = Derive::Compute(vm_, d2); Local i3 = Derive::Compute(vm_, d3); GTEST_LOG_(INFO) << "i1 = " << i1->Int32Value(vm_); GTEST_LOG_(INFO) << "i2 = " << i2->Int32Value(vm_); GTEST_LOG_(INFO) << "i3 = " << i3->Int32Value(vm_); GTEST_LOG_(INFO) << "sample_demo6_polymorphic_test ======================================="; } /* demo7 数组的使用 */ HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_Int) { LocalScope scope(vm_); uint32_t length = 5; // array length = 5 Local arrayObject = ArrayRef::New(vm_, length); uint32_t arrayLength = arrayObject->Length(vm_); uint32_t index = 1; // array index = 0 for (int i = 0; i < (int)arrayLength; i++) { Local intValue = IntegerRef::New(vm_, i * 10); ArrayRef::SetValueAt(vm_, arrayObject, i, intValue); GTEST_LOG_(INFO) << "sample_setIntValue_index_" << i << ": " << intValue->Value(); } Local resultInt = ArrayRef::GetValueAt(vm_, arrayObject, index); GTEST_LOG_(INFO) << "sample_getIntValue_index_1: " << resultInt->Value(); int inputInt = 99; // int data = 99 Local intValue = IntegerRef::New(vm_, inputInt); bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, intValue); GTEST_LOG_(INFO) << "sample_setIntValue_index_5: " << intValue->Value() << " setResult: " << setResult; int changedInt = 66; // change data = 66 Local changedIntValue = IntegerRef::New(vm_, changedInt); ArrayRef::SetValueAt(vm_, arrayObject, index, changedIntValue); GTEST_LOG_(INFO) << "sample_changedIntValue_index_1: " << changedIntValue->Value(); Local resultChangedInt = ArrayRef::GetValueAt(vm_, arrayObject, index); GTEST_LOG_(INFO) << "sample_getChangedIntValue_index_1: " << resultChangedInt->Value(); for (int i = 0; i < (int)arrayLength; i++) { Local printInt = ArrayRef::GetValueAt(vm_, arrayObject, i); GTEST_LOG_(INFO) << "sample_printIntValue_index_" << i << ": " << printInt->Value(); } } HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_Bool) { LocalScope scope(vm_); uint32_t length = 5; // array length = 5 Local arrayObject = ArrayRef::New(vm_, length); uint32_t arrayLength = arrayObject->Length(vm_); bool inputBool = true; // bool data = true uint32_t index = 0; // array index = 0 Local boolValue = BooleanRef::New(vm_, inputBool); for (int i = 0; i < (int)arrayLength; i++) { ArrayRef::SetValueAt(vm_, arrayObject, i, boolValue); GTEST_LOG_(INFO) << "sample_setBoolValue_index_" << i << ": " << boolValue->Value(); } Local resultBool = ArrayRef::GetValueAt(vm_, arrayObject, index); GTEST_LOG_(INFO) << "sample_getBoolValue_index_0: " << resultBool->Value(); bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, boolValue); GTEST_LOG_(INFO) << "sample_setBoolValue_index_5: " << boolValue->Value() << " setResult: " << setResult; bool changedBool = false; // change data = false Local changedBoolValue = BooleanRef::New(vm_, changedBool); ArrayRef::SetValueAt(vm_, arrayObject, index, changedBoolValue); GTEST_LOG_(INFO) << "sample_changedBoolValue_index_0: " << changedBoolValue->Value(); Local resultChangedBool = ArrayRef::GetValueAt(vm_, arrayObject, index); GTEST_LOG_(INFO) << "sample_getChangedBoolValue_index_0: " << resultChangedBool->Value(); for (int i = 0; i < (int)arrayLength; i++) { Local printBool = ArrayRef::GetValueAt(vm_, arrayObject, i); GTEST_LOG_(INFO) << "sample_printBoolValue_index_" << i << ": " << printBool->Value(); } } HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_Number) { LocalScope scope(vm_); uint32_t length = 5; // array length = 5 Local arrayObject = ArrayRef::New(vm_, length); uint32_t arrayLength = arrayObject->Length(vm_); uint32_t inputNumber = 40; // number data = 40 uint32_t index = 0; // array index = 0 Local numberValue = NumberRef::New(vm_, inputNumber); for (int i = 0; i < (int)arrayLength; i++) { ArrayRef::SetValueAt(vm_, arrayObject, i, numberValue); GTEST_LOG_(INFO) << "sample_setNumberValue_index_" << i << ": " << numberValue->Value(); } Local resultNumber = ArrayRef::GetValueAt(vm_, arrayObject, index); GTEST_LOG_(INFO) << "sample_getNumberValue_index_0: " << resultNumber->Value(); bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, numberValue); GTEST_LOG_(INFO) << "sample_setNumberValue_index_5: " << numberValue->Value() << " setResult: " << setResult; uint32_t changedNumber = 50; // change data = 50 Local changedNumberValue = NumberRef::New(vm_, changedNumber); ArrayRef::SetValueAt(vm_, arrayObject, index, changedNumberValue); GTEST_LOG_(INFO) << "sample_changedNumberValue_index_0: " << changedNumberValue->Value(); Local resultChangedNumber = ArrayRef::GetValueAt(vm_, arrayObject, index); GTEST_LOG_(INFO) << "sample_getChangedNumberValue_index_0: " << resultChangedNumber->Value(); for (int i = 0; i < (int)arrayLength; i++) { Local printNumber = ArrayRef::GetValueAt(vm_, arrayObject, i); GTEST_LOG_(INFO) << "sample_printNumberValue_index_" << i << ": " << printNumber->Value(); } } HWTEST_F_L0(JSNApiSampleTest, sample_ArrayRef_String) { LocalScope scope(vm_); uint32_t length = 5; // array length = 5 Local arrayObject = ArrayRef::New(vm_, length); uint32_t arrayLength = arrayObject->Length(vm_); std::string inputString = "Sample Test"; uint32_t index = 0; // array index = 0 Local stringValue = StringRef::NewFromUtf8(vm_, inputString.c_str()); for (int i = 0; i < (int)arrayLength; i++) { ArrayRef::SetValueAt(vm_, arrayObject, i, stringValue); char setBuffer[20]; stringValue->WriteUtf8(vm_, setBuffer, inputString.length()); std::string result(setBuffer); GTEST_LOG_(INFO) << "sample_setStringValue_index_" << i << ": " << result; memset_s(setBuffer, sizeof(setBuffer), 0, sizeof(setBuffer)); } Local resultString = ArrayRef::GetValueAt(vm_, arrayObject, index); char getBuffer[20]; resultString->WriteUtf8(vm_, getBuffer, inputString.length()); std::string getResult(getBuffer); GTEST_LOG_(INFO) << "sample_getStringValue_index_0: " << getResult; bool setResult = ArrayRef::SetValueAt(vm_, arrayObject, arrayLength, stringValue); GTEST_LOG_(INFO) << "sample_setStringValue_index_5" << " setResult: " << setResult; std::string changedString = "Change Test"; Local changedStringValue = StringRef::NewFromUtf8(vm_, changedString.c_str()); ArrayRef::SetValueAt(vm_, arrayObject, index, changedStringValue); Local resultChangedString = ArrayRef::GetValueAt(vm_, arrayObject, index); char changedBuffer[20]; resultChangedString->WriteUtf8(vm_, changedBuffer, changedString.length()); std::string changedResult(changedBuffer); GTEST_LOG_(INFO) << "sample_getChangedStringValue_index_0: " << changedResult; for (int i = 0; i < (int)arrayLength; i++) { Local printString = ArrayRef::GetValueAt(vm_, arrayObject, i); char printBuffer[20]; printString->WriteUtf8(vm_, printBuffer, inputString.length()); std::string printResult(printBuffer); GTEST_LOG_(INFO) << "sample_printStringValue_index_" << i << ": " << printResult; memset_s(printBuffer, sizeof(printBuffer), 0, sizeof(printBuffer)); } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Int8Array) { LocalScope scope(vm_); const int32_t length = 15; // arraybuffer length = 15 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); int8_t *ptr = (int8_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength; i++) { *ptr = int8_t(i + 10); ptr++; } int32_t byteOffset = 5; // byte offset = 5 int32_t int8ArrayLength = 6; // array length = 6 Local typedArray = Int8ArrayRef::New(vm_, arrayBuffer, byteOffset, int8ArrayLength); GTEST_LOG_(INFO) << "sample_Int8Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Int8Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Int8Array_arrayLength : " << typedArray->ArrayLength(vm_); int8_t *result = (int8_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < int8ArrayLength; i++) { int value = int8_t(*result); GTEST_LOG_(INFO) << "sample_Int8Array_getInt8ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint8Array) { LocalScope scope(vm_); const int32_t length = 15; // arraybuffer length = 15 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); uint8_t *ptr = (uint8_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength; i++) { *ptr = uint8_t(i + 10); ptr++; } int32_t byteOffset = 5; // byte offset = 5 int32_t Uint8ArrayLength = 6; // array length = 6 Local typedArray = Uint8ArrayRef::New(vm_, arrayBuffer, byteOffset, Uint8ArrayLength); GTEST_LOG_(INFO) << "sample_Uint8Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Uint8Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Uint8Array_arrayLength : " << typedArray->ArrayLength(vm_); uint8_t *result = (uint8_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < Uint8ArrayLength; i++) { int value = uint8_t(*result); GTEST_LOG_(INFO) << "sample_Uint8Array_getUint8ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint8ClampedArray) { LocalScope scope(vm_); const int32_t length = 15; // arraybuffer length = 15 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); uint8_t *ptr = (uint8_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength; i++) { *ptr = uint8_t(i + 10); ptr++; } int32_t byteOffset = 5; // byte offset = 5 int32_t uint8ArrLength = 6; // array length = 6 Local typedArray = Uint8ClampedArrayRef::New(vm_, arrayBuffer, byteOffset, uint8ArrLength); GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_arrayLength : " << typedArray->ArrayLength(vm_); uint8_t *result = (uint8_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < uint8ArrLength; i++) { int value = uint8_t(*result); GTEST_LOG_(INFO) << "sample_Uint8ClampedArray_getUint8ClampedArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Int16Array) { LocalScope scope(vm_); const int32_t length = 30; // arraybuffer length = 30 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); int16_t *ptr = (int16_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 2; i++) { *ptr = int16_t(i + 10); ptr++; } int32_t byteOffset = 4; // byte offset = 4 int32_t int16ArrayLength = 6; // array length = 6 Local typedArray = Int16ArrayRef::New(vm_, arrayBuffer, byteOffset, int16ArrayLength); GTEST_LOG_(INFO) << "sample_Int16Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Int16Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Int16Array_arrayLength : " << typedArray->ArrayLength(vm_); int16_t *result = (int16_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < int16ArrayLength; i++) { int value = int16_t(*result); GTEST_LOG_(INFO) << "sample_Int16Array_getInt16ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint16Array) { LocalScope scope(vm_); const int32_t length = 30; // arraybuffer length = 30 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); uint16_t *ptr = (uint16_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 2; i++) { *ptr = uint16_t(i + 10); ptr++; } int32_t byteOffset = 4; // byte offset = 4 int32_t uint16ArrayLength = 6; // array length = 6 Local typedArray = Uint16ArrayRef::New(vm_, arrayBuffer, byteOffset, uint16ArrayLength); GTEST_LOG_(INFO) << "sample_Uint16Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Uint16Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Uint16Array_arrayLength : " << typedArray->ArrayLength(vm_); uint16_t *result = (uint16_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < uint16ArrayLength; i++) { int value = uint16_t(*result); GTEST_LOG_(INFO) << "sample_Uint16Array_getUint16ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Int32Array) { LocalScope scope(vm_); const int32_t length = 32; // arraybuffer length = 32 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); int32_t *ptr = (int32_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 4; i++) { *ptr = int32_t(i + 10); ptr++; } int32_t byteOffset = 4; // byte offset = 4 int32_t int32ArrayLength = 6; // array length = 6 Local typedArray = Int32ArrayRef::New(vm_, arrayBuffer, byteOffset, int32ArrayLength); GTEST_LOG_(INFO) << "sample_Int32Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Int32Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Int32Array_arrayLength : " << typedArray->ArrayLength(vm_); int32_t *result = (int32_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < int32ArrayLength; i++) { int value = int32_t(*result); GTEST_LOG_(INFO) << "sample_Int32Array_getInt32ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Uint32Array) { LocalScope scope(vm_); const int32_t length = 32; // arraybuffer length = 32 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); uint32_t *ptr = (uint32_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 4; i++) { *ptr = uint32_t(i + 10); ptr++; } int32_t byteOffset = 4; // byte offset = 4 int32_t uint32ArrayLength = 6; // array length = 6 Local typedArray = Uint32ArrayRef::New(vm_, arrayBuffer, byteOffset, uint32ArrayLength); GTEST_LOG_(INFO) << "sample_Uint32Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Uint32Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Uint32Array_arrayLength : " << typedArray->ArrayLength(vm_); uint32_t *result = (uint32_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < uint32ArrayLength; i++) { int value = uint32_t(*result); GTEST_LOG_(INFO) << "sample_Uint32Array_getUint32ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Float32Array) { LocalScope scope(vm_); const int32_t length = 32; // arraybuffer length = 32 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); float *ptr = (float *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 4; i++) { *ptr = float(i + 10); ptr++; } int32_t byteOffset = 4; // byte offset = 4 int32_t float32ArrayLength = 6; // array length = 6 Local typedArray = Float32ArrayRef::New(vm_, arrayBuffer, byteOffset, float32ArrayLength); GTEST_LOG_(INFO) << "sample_Float32Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Float32Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Float32Array_arrayLength : " << typedArray->ArrayLength(vm_); float *result = (float *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < float32ArrayLength; i++) { int value = float(*result); GTEST_LOG_(INFO) << "sample_Float32Array_getFloat32ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_Float64Array) { LocalScope scope(vm_); const int32_t length = 64; // arraybuffer length = 64 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); double *ptr = (double *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 8; i++) { *ptr = double(i + 10); ptr++; } int32_t byteOffset = 8; // byte offset = 8 int32_t float64ArrayLength = 6; // array length = 6 Local typedArray = Float64ArrayRef::New(vm_, arrayBuffer, byteOffset, float64ArrayLength); GTEST_LOG_(INFO) << "sample_Float64Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Float64Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_Float64Array_arrayLength : " << typedArray->ArrayLength(vm_); double *result = (double *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < float64ArrayLength; i++) { int value = double(*result); GTEST_LOG_(INFO) << "sample_Float64Array_getFloat64ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_BigInt64Array) { LocalScope scope(vm_); const int32_t length = 64; // arraybuffer length = 64 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); int64_t *ptr = (int64_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 8; i++) { *ptr = int64_t(i * 100); ptr++; } int32_t byteOffset = 8; // byte offset = 8 int32_t bigInt64ArrayLength = 6; // array length = 6 Local typedArray = BigInt64ArrayRef::New(vm_, arrayBuffer, byteOffset, bigInt64ArrayLength); GTEST_LOG_(INFO) << "sample_BigInt64Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_BigInt64Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_BigInt64Array_arrayLength : " << typedArray->ArrayLength(vm_); int64_t *result = (int64_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < bigInt64ArrayLength; i++) { int value = int64_t(*result); GTEST_LOG_(INFO) << "sample_BigInt64Array_getBigInt64ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_TypedArrayRef_BigUint64Array) { LocalScope scope(vm_); const int32_t length = 64; // arraybuffer length = 64 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); uint64_t *ptr = (uint64_t *)arrayBuffer->GetBuffer(vm_); for (int i = 0; i < arrayLength / 8; i++) { *ptr = int64_t(i * 100); ptr++; } int32_t byteOffset = 8; // byte offset = 8 int32_t bigUint64ArrayLength = 6; // array length = 6 Local typedArray = BigUint64ArrayRef::New(vm_, arrayBuffer, byteOffset, bigUint64ArrayLength); GTEST_LOG_(INFO) << "sample_BigUint64Array_byteLength : " << typedArray->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_BigUint64Array_byteOffset : " << typedArray->ByteOffset(vm_); GTEST_LOG_(INFO) << "sample_BigUint64Array_arrayLength : " << typedArray->ArrayLength(vm_); uint64_t *result = (uint64_t *)typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_); for (int i = 0; i < bigUint64ArrayLength; i++) { int value = uint64_t(*result); GTEST_LOG_(INFO) << "sample_BigUint64Array_getBigUint64ArrayValue : " << value; result++; } } HWTEST_F_L0(JSNApiSampleTest, sample_DataViewRef) { LocalScope scope(vm_); const int32_t length = 15; // arraybuffer length = 15 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t byteOffset = 5; // byte offset = 5 int32_t dataViewLength = 7; // dataview length = 7 Local dataView = DataViewRef::New(vm_, arrayBuffer, byteOffset, dataViewLength); GTEST_LOG_(INFO) << "sample_DataView_byteLength : " << dataView->ByteLength(); GTEST_LOG_(INFO) << "sample_DataView_byteOffset : " << dataView->ByteOffset(); GTEST_LOG_(INFO) << "sample_DataView_getArrayBuffer : " << dataView->GetArrayBuffer(vm_)->GetBuffer(vm_); } HWTEST_F_L0(JSNApiSampleTest, sample_ArrayBuffer_New_Detach) { LocalScope scope(vm_); const int32_t length = 32; // arraybuffer length = 32 Local arrayBuffer = ArrayBufferRef::New(vm_, length); int32_t arrayLength = arrayBuffer->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_ArrayBuffer_byteLength : " << arrayLength; GTEST_LOG_(INFO) << "sample_ArrayBuffer_getArrayBuffer : " << arrayBuffer->GetBuffer(vm_); arrayBuffer->Detach(vm_); GTEST_LOG_(INFO) << "sample_ArrayBuffer_getDetachArrayBuffer : " << arrayBuffer->GetBuffer(vm_); bool result = arrayBuffer->IsDetach(vm_); GTEST_LOG_(INFO) << "sample_ArrayBuffer_getIsDetach : " << result; } HWTEST_F_L0(JSNApiSampleTest, sample_ArrayBufferWithBuffer_New_Detach) { static bool isFree = false; struct Data { int32_t length; }; const int32_t length = 5; // arraybuffer length = 5 Data *data = new Data(); data->length = length; NativePointerCallback deleter = [](void *env, void *buffer, void *data) -> void { delete[] reinterpret_cast(buffer); Data *currentData = reinterpret_cast(data); delete currentData; isFree = true; }; LocalScope scope(vm_); uint8_t *buffer = new uint8_t[length](); Local arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data); GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_byteLength : " << arrayBuffer->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_getArrayBuffer : " << arrayBuffer->GetBuffer(vm_); arrayBuffer->Detach(vm_); GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_getDetachArrayBuffer : " << arrayBuffer->GetBuffer(vm_); bool result = arrayBuffer->IsDetach(vm_); GTEST_LOG_(INFO) << "sample_ArrayBufferWithBuffer_getIsDetach : " << result; } HWTEST_F_L0(JSNApiSampleTest, sample_Buffer_New_GetBuffer) { LocalScope scope(vm_); const int32_t length = 5; // buffer length = 5 Local buffer = BufferRef::New(vm_, length); GTEST_LOG_(INFO) << "sample_Buffer_byteLength : " << buffer->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_Buffer_getBuffer : " << buffer->GetBuffer(vm_); } HWTEST_F_L0(JSNApiSampleTest, sample_BufferWithBuffer_New_GetBuffer) { static bool isFree = false; struct Data { int32_t length; }; const int32_t length = 5; // buffer length = 5 Data *data = new Data(); data->length = length; NativePointerCallback deleter = [](void *env, void *buffer, void *data) -> void { delete[] reinterpret_cast(buffer); Data *currentData = reinterpret_cast(data); delete currentData; isFree = true; }; LocalScope scope(vm_); uint8_t *buffer = new uint8_t[length](); Local bufferObj = BufferRef::New(vm_, buffer, length, deleter, data); GTEST_LOG_(INFO) << "sample_bufferWithBuffer_byteLength : " << bufferObj->ByteLength(vm_); GTEST_LOG_(INFO) << "sample_bufferWithBuffer_getBuffer : " << bufferObj->GetBuffer(vm_); } /* domo8 异步操作。 ts: * new Promise(function (resolve, reject) { * var a = 0; * var b = 1; * if (b == 0) reject("Divide zero"); * else resolve(a / b); * }).then(function (value) { * console.log("a / b = " + value); * }).catch(function (err) { * console.log(err); * }).finally(function () { * console.log("End"); * }); */ HWTEST_F_L0(JSNApiSampleTest, sample_demo8_async_test_1) { GTEST_LOG_(INFO) << "sample_demo8_async_test_1 ======================================="; LocalScope scope(vm_); Local capability = PromiseCapabilityRef::New(vm_); capability->GetPromise(vm_) ->Then(vm_, FunctionRef::New(vm_, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); Local jsNum = runtimeInfo->GetCallArgRef(0); int num = jsNum->Int32Value(vm); // ts: console.log("a / b = " + value); GTEST_LOG_(INFO) << "a / b = " << num; return JSValueRef::Undefined(vm); })) ->Catch(vm_, FunctionRef::New(vm_, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); Local jsStr = runtimeInfo->GetCallArgRef(0); std::string err = jsStr->ToString(vm)->ToString(vm); // ts: console.log(err); GTEST_LOG_(INFO) << err; return JSValueRef::Undefined(vm); })) ->Finally(vm_, FunctionRef::New(vm_, // 函数体 [](JsiRuntimeCallInfo *runtimeInfo) -> Local { EcmaVM *vm = runtimeInfo->GetVM(); LocalScope scope(vm); // ts: console.log("End"); GTEST_LOG_(INFO) << "End"; return JSValueRef::Undefined(vm); })); int a = 0; int b = 0; if (b == 0) { capability->Reject(vm_, StringRef::NewFromUtf8(vm_, "Divide zero")); } else { capability->Resolve(vm_, NumberRef::New(vm_, int(a / b))); } GTEST_LOG_(INFO) << "sample_demo8_async_test_1 ======================================="; } // JSValueRef转为字符串输出。 std::string jsValue2String(EcmaVM *vm, Local &jsVal) { if (jsVal->IsString(vm)) { return "type string, val : " + jsVal->ToString(vm)->ToString(vm); } else if (jsVal->IsNumber()) { return "type number, val : " + std::to_string(jsVal->Int32Value(vm)); } else if (jsVal->IsBoolean()) { return "type bool, val : " + std::to_string(jsVal->BooleaValue(vm)); } else if (jsVal->IsSymbol(vm)) { Local symbol = jsVal; return "type symbol, val : " + symbol->GetDescription(vm)->ToString(vm); } else { return "type other : " + jsVal->ToString(vm)->ToString(vm); } } void MapSetValue(EcmaVM *vm, Local &map, Local symbolKey) { map->Set(vm, StringRef::NewFromUtf8(vm, "key1"), StringRef::NewFromUtf8(vm, "val1")); int num2 = 222; // random number map->Set(vm, StringRef::NewFromUtf8(vm, "key2"), NumberRef::New(vm, num2)); map->Set(vm, StringRef::NewFromUtf8(vm, "key3"), BooleanRef::New(vm, true)); map->Set(vm, StringRef::NewFromUtf8(vm, "key4"), SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "val4"))); int num5 = 55; // random number map->Set(vm, IntegerRef::New(vm, num5), StringRef::NewFromUtf8(vm, "val5")); int num61 = 66; // random number int num62 = 666; // random number map->Set(vm, IntegerRef::New(vm, num61), IntegerRef::New(vm, num62)); map->Set(vm, BooleanRef::New(vm, true), StringRef::NewFromUtf8(vm, "val7")); map->Set(vm, symbolKey, StringRef::NewFromUtf8(vm, "val8")); } void MapGetValue(EcmaVM *vm, Local &map, Local symbolKey) { Local val1 = map->Get(vm, StringRef::NewFromUtf8(vm, "key1")); bool val1IsString = val1->IsString(vm); GTEST_LOG_(INFO) << "key1 : IsString:" << val1IsString << " val:" << val1->ToString(vm)->ToString(vm); Local val2 = map->Get(vm, StringRef::NewFromUtf8(vm, "key2")); bool val2IsNumber = val2->IsNumber(); GTEST_LOG_(INFO) << "key2 : IsNumber:" << val2IsNumber << " val:" << val2->Int32Value(vm); Local val3 = map->Get(vm, StringRef::NewFromUtf8(vm, "key3")); bool val3IsBoolean = val3->IsBoolean(); GTEST_LOG_(INFO) << "key3 : IsBoolean:" << val3IsBoolean << " val:" << val3->BooleaValue(vm); Local val4 = map->Get(vm, StringRef::NewFromUtf8(vm, "key4")); bool val4IsSymbol = val4->IsSymbol(vm); Local val4Symbol = val4; GTEST_LOG_(INFO) << "key4 : IsSymbol:" << val4IsSymbol << " val:" << val4Symbol->GetDescription(vm)->ToString(vm); int num5 = 55; // random number Local val5 = map->Get(vm, IntegerRef::New(vm, num5)); GTEST_LOG_(INFO) << "55 : " << val5->ToString(vm)->ToString(vm); int num6 = 66; // random number Local val6 = map->Get(vm, IntegerRef::New(vm, num6)); GTEST_LOG_(INFO) << "66 : " << val6->Int32Value(vm); Local val7 = map->Get(vm, BooleanRef::New(vm, true)); GTEST_LOG_(INFO) << "true : " << val7->ToString(vm)->ToString(vm); Local val8 = map->Get(vm, symbolKey); GTEST_LOG_(INFO) << "SymbolRef(key8) : " << val8->ToString(vm)->ToString(vm); Local val82 = map->Get(vm, SymbolRef::New(vm, StringRef::NewFromUtf8(vm, "key8"))); GTEST_LOG_(INFO) << "new SymbolRef(key8) is Undefined : " << val82->IsUndefined(); int32_t size = map->GetSize(vm); GTEST_LOG_(INFO) << "size : " << size; int32_t totalElement = map->GetTotalElements(vm); GTEST_LOG_(INFO) << "total element : " << totalElement; for (int i = 0; i < size; ++i) { Local jsKey = map->GetKey(vm, i); Local jsVal = map->GetValue(vm, i); GTEST_LOG_(INFO) << "for map index : " << i << " key : " << jsValue2String(vm, jsKey) << " val : " << jsValue2String(vm, jsVal); } } void MapIteratorGetValue(EcmaVM *vm, Local &map) { Local mapIter = MapIteratorRef::New(vm, map); ecmascript::EcmaRuntimeCallInfo *mapIterInfo = mapIter->GetEcmaRuntimeCallInfo(vm); Local kind = mapIter->GetKind(vm); GTEST_LOG_(INFO) << "Map Iterator kind : " << kind->ToString(vm); for (Local array = MapIteratorRef::Next(vm, mapIterInfo); array->IsArray(vm); array = MapIteratorRef::Next(vm, mapIterInfo)) { int index = mapIter->GetIndex() - 1; Local jsKey = ArrayRef::GetValueAt(vm, array, 0); Local jsVal = ArrayRef::GetValueAt(vm, array, 1); GTEST_LOG_(INFO) << "for map iterator index : " << index << " key : " << jsValue2String(vm, jsKey) << " val : " << jsValue2String(vm, jsVal); } } /* demo9 Map,MapIterator 的操作。 */ HWTEST_F_L0(JSNApiSampleTest, sample_demo9_map_test_1_MapRef_MapIteratorRef) { GTEST_LOG_(INFO) << "sample_demo9_map_test_1_MapRef_MapIteratorRef ======================================="; LocalScope scope(vm_); Local map = MapRef::New(vm_); Local symbolKey = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "key8")); MapSetValue(vm_, map, symbolKey); MapGetValue(vm_, map, symbolKey); MapIteratorGetValue(vm_, map); GTEST_LOG_(INFO) << "sample_demo9_map_test_1_MapRef_MapIteratorRef ======================================="; } /* demo9 WeakMap 的操作。 */ HWTEST_F_L0(JSNApiSampleTest, sample_demo9_map_test_2_WeakMapref) { GTEST_LOG_(INFO) << "sample_demo9_map_test_2_WeakMapref ======================================="; LocalScope scope(vm_); Local weakMap = WeakMapRef::New(vm_); weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val1")); int num2 = 222; // random number weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), NumberRef::New(vm_, num2)); weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key3"), BooleanRef::New(vm_, true)); weakMap->Set(vm_, StringRef::NewFromUtf8(vm_, "key4"), SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "val4"))); weakMap->Set(vm_, IntegerRef::New(vm_, 55), StringRef::NewFromUtf8(vm_, "val5")); int num6 = 666; // random number weakMap->Set(vm_, IntegerRef::New(vm_, 66), IntegerRef::New(vm_, num6)); weakMap->Set(vm_, BooleanRef::New(vm_, true), StringRef::NewFromUtf8(vm_, "val7")); Local key8 = SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "key8")); weakMap->Set(vm_, key8, StringRef::NewFromUtf8(vm_, "val8")); int size = weakMap->GetSize(vm_); GTEST_LOG_(INFO) << "size : " << size; int32_t totalElements = weakMap->GetTotalElements(vm_); GTEST_LOG_(INFO) << "total elements : " << totalElements; for (int i = 0; i < size; ++i) { Local jsKey = weakMap->GetKey(vm_, i); Local jsVal = weakMap->GetValue(vm_, i); GTEST_LOG_(INFO) << "for WeakMap index : " << i << " key : " << jsValue2String(vm_, jsKey) << " val : " << jsValue2String(vm_, jsVal); } bool hasKey2 = weakMap->Has(vm_, StringRef::NewFromUtf8(vm_, "key2")); GTEST_LOG_(INFO) << "Has Key2 : " << hasKey2; bool hasKey222 = weakMap->Has(vm_, StringRef::NewFromUtf8(vm_, "key222")); GTEST_LOG_(INFO) << "Has key222 : " << hasKey222; GTEST_LOG_(INFO) << "sample_demo9_map_test_2_WeakMapref ======================================="; } /* demo10 set 的使用 */ HWTEST_F_L0(JSNApiSampleTest, sample_demo10_set) { GTEST_LOG_(INFO) << "sample_demo10_set ======================================="; LocalScope scope(vm_); Local set = SetRef::New(vm_); set->Add(vm_, StringRef::NewFromUtf8(vm_, "val1")); int num2 = 222; // random number set->Add(vm_, NumberRef::New(vm_, num2)); set->Add(vm_, BooleanRef::New(vm_, true)); set->Add(vm_, SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "val4"))); set->Add(vm_, StringRef::NewFromUtf8(vm_, "val5")); int num6 = 666; // random number set->Add(vm_, IntegerRef::New(vm_, num6)); int32_t size = set->GetSize(vm_); GTEST_LOG_(INFO) << "size : " << size; int32_t totalElement = set->GetTotalElements(vm_); GTEST_LOG_(INFO) << "total element : " << totalElement; for (int i = 0; i < size; ++i) { Local jsVal = set->GetValue(vm_, i); GTEST_LOG_(INFO) << "for set index : " << i << " val : " << jsValue2String(vm_, jsVal); } // Iterator Local setIter = SetIteratorRef::New(vm_, set); ecmascript::EcmaRuntimeCallInfo *info = setIter->GetEcmaRuntimeCallInfo(vm_); Local kind = setIter->GetKind(vm_); GTEST_LOG_(INFO) << "Set Iterator kind : " << kind->ToString(vm_); for (Local array = SetIteratorRef::Next(vm_, info); array->IsArray(vm_); array = SetIteratorRef::Next(vm_, info)) { int index = setIter->GetIndex() - 1; Local jsVal = ArrayRef::GetValueAt(vm_, array, 1); GTEST_LOG_(INFO) << "for set iterator index : " << index << " val : " << jsValue2String(vm_, jsVal); } GTEST_LOG_(INFO) << "sample_demo10_set ======================================="; } /* demo10 WeakSet 的使用 */ HWTEST_F_L0(JSNApiSampleTest, sample_demo10_weakset) { GTEST_LOG_(INFO) << "sample_demo10_weakset ======================================="; LocalScope scope(vm_); Local weakSet = WeakSetRef::New(vm_); weakSet->Add(vm_, StringRef::NewFromUtf8(vm_, "val1")); int num2 = 666; // random number weakSet->Add(vm_, NumberRef::New(vm_, num2)); weakSet->Add(vm_, BooleanRef::New(vm_, true)); weakSet->Add(vm_, SymbolRef::New(vm_, StringRef::NewFromUtf8(vm_, "val4"))); weakSet->Add(vm_, StringRef::NewFromUtf8(vm_, "val5")); int num6 = 666; // random number weakSet->Add(vm_, IntegerRef::New(vm_, num6)); int32_t size = weakSet->GetSize(vm_); GTEST_LOG_(INFO) << "size : " << size; int32_t totalElement = weakSet->GetTotalElements(vm_); GTEST_LOG_(INFO) << "total element : " << totalElement; for (int i = 0; i < size; ++i) { Local jsVal = weakSet->GetValue(vm_, i); GTEST_LOG_(INFO) << "for weakset index : " << i << " val : " << jsValue2String(vm_, jsVal); } GTEST_LOG_(INFO) << "sample_demo10_weakset ======================================="; } // json对象获取值。 void JsonObjGetValue(EcmaVM *vm, Local obj) { Local jsVal1 = obj->Get(vm, StringRef::NewFromUtf8(vm, "str1")); bool jsVal1IsString = jsVal1->IsString(vm); Local val1 = jsVal1->ToString(vm); GTEST_LOG_(INFO) << "str1 : is string : " << jsVal1IsString << " value : " << val1->ToString(vm); Local jsVal2 = obj->Get(vm, StringRef::NewFromUtf8(vm, "str2")); bool jsVal2IsNumber = jsVal2->IsNumber(); int val2 = jsVal2->Int32Value(vm); GTEST_LOG_(INFO) << "str2 : is number : " << jsVal2IsNumber << " value : " << val2; Local jsVal3 = obj->Get(vm, StringRef::NewFromUtf8(vm, "333")); int val3 = jsVal3->Int32Value(vm); GTEST_LOG_(INFO) << "333 : " << val3; Local jsVal4 = obj->Get(vm, StringRef::NewFromUtf8(vm, "444")); Local val4 = jsVal4->ToString(vm); GTEST_LOG_(INFO) << "str4 : " << val4->ToString(vm); Local jsVal8 = obj->Get(vm, StringRef::NewFromUtf8(vm, "b8")); bool jsVal8IsBool = jsVal8->IsBoolean(); Local val8Ref = jsVal8; bool val8 = val8Ref->Value(); GTEST_LOG_(INFO) << "b8 is bool : " << jsVal8IsBool << " val : " << val8; } // json对象获取数组。 void JsonObjGetArray(EcmaVM *vm, Local obj) { Local jsVal5 = obj->Get(vm, StringRef::NewFromUtf8(vm, "arr5")); Local val5Obj = jsVal5; int length = val5Obj->Get(vm, StringRef::NewFromUtf8(vm, "length"))->Int32Value(vm); GTEST_LOG_(INFO) << "arr5 length : " << length; for (int i = 0; i < length; ++i) { Local val5Item = val5Obj->Get(vm, NumberRef::New(vm, i)); GTEST_LOG_(INFO) << "arr5 : " << i << " " << val5Item->Int32Value(vm); } Local val5Arr = jsVal5; uint32_t length2 = val5Arr->Length(vm); GTEST_LOG_(INFO) << "arr5 length2 : " << length2; for (uint32_t i = 0; i < length2; ++i) { Local val5Item = ArrayRef::GetValueAt(vm, val5Arr, i); GTEST_LOG_(INFO) << "arr5 : " << i << " " << val5Item->Int32Value(vm); } Local jsVal6 = obj->Get(vm, StringRef::NewFromUtf8(vm, "arr6")); Local val6Obj = jsVal6; int length3 = val6Obj->Get(vm, StringRef::NewFromUtf8(vm, "length"))->Int32Value(vm); GTEST_LOG_(INFO) << "arr6 length : " << length3; for (int i = 0; i < length3; ++i) { Local val6Item = val6Obj->Get(vm, NumberRef::New(vm, i)); GTEST_LOG_(INFO) << "arr6 : " << i << " " << val6Item->ToString(vm)->ToString(vm); } } // json对象获取对象。 void JsonObjGetObject(EcmaVM *vm, Local obj) { Local jsVal7 = obj->Get(vm, StringRef::NewFromUtf8(vm, "data7")); Local val7Obj = jsVal7->ToObject(vm); Local val7ObjKeys = val7Obj->GetOwnPropertyNames(vm); for (uint32_t i = 0; i < val7ObjKeys->Length(vm); ++i) { Local itemKey = ArrayRef::GetValueAt(vm, val7ObjKeys, i); Local itemVal = val7Obj->Get(vm, itemKey); GTEST_LOG_(INFO) << "data7 : item index:" << i << " Key:" << itemKey->ToString(vm)->ToString(vm) << " val:" << itemVal->ToString(vm)->ToString(vm); } } /* demo11 json 测试,json字符串 转 obj。 注意key不能是纯数字。 json: * { * "str1": "val1", * "str2": 222, * "333": 456, * "444": "val4", * "arr5": [ * 51, * 52, * 53, * 54, * 55 * ], * "arr6": [ * "str61", * "str62", * "str63", * "str64" * ], * "data7": { * "key71": "val71", * "key72": "val72" * }, * "b8": true * } */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_1_parse_object) { GTEST_LOG_(INFO) << "sample_demo11_json_test_1_parse_object ======================================="; LocalScope scope(vm_); std::string jsonStr = "{\"str1\":\"val1\",\"str2\":222,\"333\":456,\"444\":\"val4\",\"arr5\":[51,52,53,54,55],\"arr6\":[\"str61\"," "\"str62\",\"str63\",\"str64\"],\"data7\":{\"key71\":\"val71\",\"key72\":\"val72\"},\"b8\":true}"; Local jsObj = JSON::Parse(vm_, StringRef::NewFromUtf8(vm_, jsonStr.c_str())); Local obj = jsObj->ToObject(vm_); JsonObjGetValue(vm_, obj); JsonObjGetArray(vm_, obj); JsonObjGetObject(vm_, obj); GTEST_LOG_(INFO) << "sample_demo11_json_test_1_parse_object ======================================="; } /* demo11 json 测试,obj转json字符串。 json: * { * "key1": "val1", * "key2": 123, * "333": "val3", * "arr4": [ * "val40", * "val41", * "val42", * "val43" * ], * "arr5": [ * 50, * 51, * 52, * 53 * ], * "b6": true, * "obj7": { * "key71": "val71", * "key72": "val72", * "key73": "val73" * } * } */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_2_stringify_object) { GTEST_LOG_(INFO) << "sample_demo11_json_test_2_stringify_object ======================================="; LocalScope scope(vm_); Local obj = ObjectRef::New(vm_); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val1")); int num2 = 123; // random number obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), NumberRef::New(vm_, num2)); int num3 = 333; // random number obj->Set(vm_, NumberRef::New(vm_, num3), StringRef::NewFromUtf8(vm_, "val3")); Local arr4 = ArrayRef::New(vm_); ArrayRef::SetValueAt(vm_, arr4, 0, StringRef::NewFromUtf8(vm_, "val40")); ArrayRef::SetValueAt(vm_, arr4, 1, StringRef::NewFromUtf8(vm_, "val41")); ArrayRef::SetValueAt(vm_, arr4, 2, StringRef::NewFromUtf8(vm_, "val42")); ArrayRef::SetValueAt(vm_, arr4, 3, StringRef::NewFromUtf8(vm_, "val43")); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "arr4"), arr4); Local arr5 = ArrayRef::New(vm_); int num50 = 50; // random number int num51 = 51; // random number int num52 = 52; // random number int num53 = 53; // random number ArrayRef::SetValueAt(vm_, arr5, 0, IntegerRef::New(vm_, num50)); ArrayRef::SetValueAt(vm_, arr5, 1, IntegerRef::New(vm_, num51)); ArrayRef::SetValueAt(vm_, arr5, 2, IntegerRef::New(vm_, num52)); ArrayRef::SetValueAt(vm_, arr5, 3, IntegerRef::New(vm_, num53)); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "arr5"), arr5); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "b6"), BooleanRef::New(vm_, true)); Local obj7 = ObjectRef::New(vm_); obj7->Set(vm_, StringRef::NewFromUtf8(vm_, "key71"), StringRef::NewFromUtf8(vm_, "val71")); obj7->Set(vm_, StringRef::NewFromUtf8(vm_, "key72"), StringRef::NewFromUtf8(vm_, "val72")); obj7->Set(vm_, StringRef::NewFromUtf8(vm_, "key73"), StringRef::NewFromUtf8(vm_, "val73")); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "obj7"), obj7); Local jsStr = JSON::Stringify(vm_, obj); GTEST_LOG_(INFO) << "jsStr is String : " << jsStr->IsString(vm_); Local strRef = jsStr->ToString(vm_); std::string str = strRef->ToString(vm_); GTEST_LOG_(INFO) << "json : " << str; GTEST_LOG_(INFO) << "sample_demo11_json_test_2_stringify_object ======================================="; } /* demo11 json 测试,json字符串转为数组。 json: * [51,52,53,54,55] */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array1) { GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array1 ======================================="; LocalScope scope(vm_); // 随机的一个 json 数字 数组。 [51,52,53,54,55] Local arrStr1 = StringRef::NewFromUtf8(vm_, "[51,52,53,54,55]"); Local jsArr1 = JSON::Parse(vm_, arrStr1); bool jsArr1IsArr = jsArr1->IsArray(vm_); GTEST_LOG_(INFO) << "jsArr1 is array : " << jsArr1IsArr; Local arr1 = jsArr1; uint32_t arr1Length = arr1->Length(vm_); GTEST_LOG_(INFO) << "arr1 length : " << arr1Length; for (uint32_t i = 0; i < arr1Length; ++i) { Local arr1Item = ArrayRef::GetValueAt(vm_, arr1, i); if (arr1Item->IsNumber()) { int num = arr1Item->Int32Value(vm_); GTEST_LOG_(INFO) << "arr1 index : " << i << " value : " << num; } else { GTEST_LOG_(INFO) << "arr1 index : " << i << " not number !"; } } GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array1 ======================================="; } /* demo11 json 测试,json字符串转为数组。 json: * ["a1","a2","a3","a4","a5","a6"] */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array2) { GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array2 ======================================="; LocalScope scope(vm_); // 随机的一个json字符串数组。 ["a1","a2","a3","a4","a5","a6"] Local arrStr2 = StringRef::NewFromUtf8(vm_, "[\"a1\",\"a2\",\"a3\",\"a4\",\"a5\",\"a6\"]"); Local jsArr2 = JSON::Parse(vm_, arrStr2); bool jsArr2IsArr = jsArr2->IsArray(vm_); GTEST_LOG_(INFO) << "jsArr2 is array : " << jsArr2IsArr; Local arr2 = jsArr2; uint32_t arr2Length = arr2->Length(vm_); GTEST_LOG_(INFO) << "arr2 length : " << arr2Length; for (uint32_t i = 0; i < arr2Length; ++i) { Local arr2Item = ArrayRef::GetValueAt(vm_, arr2, i); std::string str = arr2Item->ToString(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "arr2 index : " << i << " value : " << str; } GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array2 ======================================="; } /* demo11 json 测试,json字符串转为数组。 json: * [true,true,false,false,true] */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array3) { GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array3 ======================================="; LocalScope scope(vm_); Local arrStr3 = StringRef::NewFromUtf8(vm_, "[true,true,false,false,true]"); Local jsArr3 = JSON::Parse(vm_, arrStr3); bool jsArr3IsArr = jsArr3->IsArray(vm_); GTEST_LOG_(INFO) << "jsArr3 is array : " << jsArr3IsArr; Local arr3 = jsArr3; uint32_t arr3Length = arr3->Length(vm_); GTEST_LOG_(INFO) << "arr3 length : " << arr3Length; for (uint32_t i = 0; i < arr3Length; ++i) { Local arr3Item = ArrayRef::GetValueAt(vm_, arr3, i); int b = arr3Item->BooleaValue(vm_); GTEST_LOG_(INFO) << "arr3 index : " << i << " value : " << b; } GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array3 ======================================="; } /* demo11 json 测试,json字符串转为数组。 json: * [ * { * "key1": "val11", * "key2": "val12" * }, * { * "key1": "val21", * "key2": "val22" * }, * { * "key1": "val31", * "key2": "val32" * } * ] */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array4) { GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array4 ======================================="; LocalScope scope(vm_); // json 对象数组。 // json: [{"key1": "val11","key2": "val12"},{"key1": "val21","key2": "val22"},{"key1": "val31","key2": "val32"}] Local arrStr4 = StringRef::NewFromUtf8(vm_, "[{\"key1\":\"val11\",\"key2\":\"val12\"},{\"key1\":\"val21\",\"key2\":\"val22\"},{" "\"key1\":\"val31\",\"key2\":\"val32\"}]"); Local jsArr4 = JSON::Parse(vm_, arrStr4); bool jsArr4IsArr = jsArr4->IsArray(vm_); GTEST_LOG_(INFO) << "jsArr4 is array : " << jsArr4IsArr; Local arr4 = jsArr4; uint32_t arr4Length = arr4->Length(vm_); GTEST_LOG_(INFO) << "arr4 length : " << arr4Length; for (uint32_t i = 0; i < arr4Length; ++i) { Local jsArr4Item = ArrayRef::GetValueAt(vm_, arr4, i); Local obj = jsArr4Item->ToObject(vm_); Local objVal1 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key1")); Local objVal2 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key2")); GTEST_LOG_(INFO) << "arr4 index : " << i << " key1 : " << objVal1->ToString(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "arr4 index : " << i << " key2 : " << objVal2->ToString(vm_)->ToString(vm_); } GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array4 ======================================="; } /* demo11 json 测试,json字符串转为数组。 json: * ["val1",222,true,{"key1": "val1","key2": "val2"}] */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_3_parse_array5) { GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array5 ======================================="; LocalScope scope(vm_); // json 数组: ["val1",222,true,{"key1": "val1","key2": "val2"}] Local arrStr5 = StringRef::NewFromUtf8(vm_, "[\"val1\",222,true,{\"key1\":\"val1\",\"key2\":\"val1\"}]"); Local jsArr5 = JSON::Parse(vm_, arrStr5); bool jsArr5IsArr = jsArr5->IsArray(vm_); GTEST_LOG_(INFO) << "jsArr5 is array : " << jsArr5IsArr; Local arr5 = jsArr5; uint32_t arr5Length = arr5->Length(vm_); GTEST_LOG_(INFO) << "arr5 length : " << arr5Length; for (uint32_t i = 0; i < arr5Length; ++i) { Local arr5Item = ArrayRef::GetValueAt(vm_, arr5, i); if (arr5Item->IsString(vm_)) { GTEST_LOG_(INFO) << "arr5 index : " << i << " value : " << arr5Item->ToString(vm_)->ToString(vm_); } else if (arr5Item->IsNumber()) { GTEST_LOG_(INFO) << "arr5 index : " << i << " value : " << arr5Item->Int32Value(vm_); } else if (arr5Item->IsBoolean()) { GTEST_LOG_(INFO) << "arr5 index : " << i << " value : " << arr5Item->ToBoolean(vm_)->Value(); } else if (arr5Item->IsObject(vm_)) { Local obj = arr5Item->ToObject(vm_); Local val1 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key1")); Local val2 = obj->Get(vm_, StringRef::NewFromUtf8(vm_, "key2")); GTEST_LOG_(INFO) << "arr5 index : " << i << " key1 : " << val1->ToString(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "arr5 index : " << i << " key2 : " << val2->ToString(vm_)->ToString(vm_); } else { GTEST_LOG_(INFO) << "arr5 index : " << i << " not type !"; } } GTEST_LOG_(INFO) << "sample_demo11_json_test_3_parse_array5 ======================================="; } /* demo11 json 测试,数组转json字符串。 json: * ["val0","val1","val2","val3"] * [ * { * "key1": "val11", * "key2": "val12", * "key3": "val13" * }, * { * "key1": "val21", * "key2": "val22", * "key3": "val23" * } * ] * [ * "val1", * 222, * true, * { * "key1": "val1", * "key2": "val2" * } * ] */ HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_4_stringify_array1) { GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array1 ======================================="; LocalScope scope(vm_); Local arr = ArrayRef::New(vm_); ArrayRef::SetValueAt(vm_, arr, 0, StringRef::NewFromUtf8(vm_, "val0")); ArrayRef::SetValueAt(vm_, arr, 1, StringRef::NewFromUtf8(vm_, "val1")); ArrayRef::SetValueAt(vm_, arr, 2, StringRef::NewFromUtf8(vm_, "val2")); ArrayRef::SetValueAt(vm_, arr, 3, StringRef::NewFromUtf8(vm_, "val3")); Local json1 = JSON::Stringify(vm_, arr); GTEST_LOG_(INFO) << " js arr 1 json : " << json1->ToString(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array1 ======================================="; } HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_4_stringify_array2) { GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array2 ======================================="; Local obj1 = ObjectRef::New(vm_); obj1->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val11")); obj1->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), StringRef::NewFromUtf8(vm_, "val12")); obj1->Set(vm_, StringRef::NewFromUtf8(vm_, "key3"), StringRef::NewFromUtf8(vm_, "val13")); Local obj2 = ObjectRef::New(vm_); obj2->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val21")); obj2->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), StringRef::NewFromUtf8(vm_, "val22")); obj2->Set(vm_, StringRef::NewFromUtf8(vm_, "key3"), StringRef::NewFromUtf8(vm_, "val23")); Local arr = ArrayRef::New(vm_); ArrayRef::SetValueAt(vm_, arr, 0, obj1); ArrayRef::SetValueAt(vm_, arr, 1, obj2); Local json2 = JSON::Stringify(vm_, arr); GTEST_LOG_(INFO) << " js arr 2 json : " << json2->ToString(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array2 ======================================="; } HWTEST_F_L0(JSNApiSampleTest, sample_demo11_json_test_4_stringify_array3) { GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array3 ======================================="; Local obj = ObjectRef::New(vm_); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key1"), StringRef::NewFromUtf8(vm_, "val1")); obj->Set(vm_, StringRef::NewFromUtf8(vm_, "key2"), StringRef::NewFromUtf8(vm_, "val2")); Local arr = ArrayRef::New(vm_); ArrayRef::SetValueAt(vm_, arr, 0, StringRef::NewFromUtf8(vm_, "val1")); int num2 = 222; // random number ArrayRef::SetValueAt(vm_, arr, 1, NumberRef::New(vm_, num2)); ArrayRef::SetValueAt(vm_, arr, 2, BooleanRef::New(vm_, true)); ArrayRef::SetValueAt(vm_, arr, 3, obj); Local json3 = JSON::Stringify(vm_, arr); GTEST_LOG_(INFO) << " js arr 3 json : " << json3->ToString(vm_)->ToString(vm_); GTEST_LOG_(INFO) << "sample_demo11_json_test_4_stringify_array3 ======================================="; } /* demo12 异常的抛出和处理 */ // 抛出异常的测试函数 Local ThrowErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:Error"); Local error = Exception::Error(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowRangeErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:RangeError"); Local error = Exception::RangeError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowReferenceErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:ReferenceError"); Local error = Exception::ReferenceError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowSyntaxErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:SyntaxError"); Local error = Exception::SyntaxError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowTypeErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:TypeError"); Local error = Exception::TypeError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowAggregateErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:AggregateError"); Local error = Exception::AggregateError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowEvalErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:EvalError"); Local error = Exception::EvalError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowOOMErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:OOMError"); Local error = Exception::OOMError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } Local ThrowTerminationErrorFuncTest(const EcmaVM *vm, Local par) { int i = par->Int32Value(vm); if (i == 0) { std::string errStr = std::string("function:").append(__func__).append("err:TerminationError"); Local error = Exception::TerminationError(vm, StringRef::NewFromUtf8(vm, errStr.c_str())); JSNApi::ThrowException(vm, error); return JSValueRef::Undefined(vm); } int num = 2; // 函数的功能,原数字的2倍。 return NumberRef::New(vm, i * num); } // 处理异常,用 JSNApi 类中的函数。 void ClearAndPrintException4JSNApi(const EcmaVM *vm, const std::string log) { if (!JSNApi::HasPendingException(vm)) { GTEST_LOG_(INFO) << log << " no exception ."; return; } JSNApi::PrintExceptionInfo(vm); Local exception = JSNApi::GetAndClearUncaughtException(vm); std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm); std::string exceptionMessage = exception->Get(vm, StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm); std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm); GTEST_LOG_(INFO) << log << " exception name : " << exceptionName; GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage; GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack; }; // 处理异常,用 TryCatch 类中的函数。 void ClearAndPrintException4TryCatch1(const EcmaVM *vm, const std::string log) { TryCatch tryCatch(vm); if (!tryCatch.HasCaught()) { GTEST_LOG_(INFO) << log << " no exception ."; return; } Local exception = tryCatch.GetAndClearException(); std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm); std::string exceptionMessage = exception->Get(vm, StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm); std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm); GTEST_LOG_(INFO) << log << " exception name : " << exceptionName; GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage; GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack; }; // 处理异常,用 TryCatch 类中的函数。 void ClearAndPrintException4TryCatch2(const EcmaVM *vm, const std::string log) { TryCatch tryCatch(vm); if (!tryCatch.HasCaught()) { GTEST_LOG_(INFO) << log << " no exception ."; return; } Local exception = tryCatch.GetException(); tryCatch.ClearException(); std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm); std::string exceptionMessage = exception->Get(vm, StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm); std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm); GTEST_LOG_(INFO) << log << " exception name : " << exceptionName; GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage; GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack; tryCatch.Rethrow(); }; // 异常没有处理重新抛出异常,用 TryCatch 类中的函数。 void PrintAndRethrowException4TryCatch3(const EcmaVM *vm, const std::string log) { TryCatch tryCatch(vm); if (!tryCatch.HasCaught()) { GTEST_LOG_(INFO) << log << " no exception ."; return; } Local exception = tryCatch.GetAndClearException(); std::string exceptionName = exception->Get(vm, StringRef::NewFromUtf8(vm, "name"))->ToString(vm)->ToString(vm); std::string exceptionMessage = exception->Get(vm, StringRef::NewFromUtf8(vm, "message"))->ToString(vm)->ToString(vm); std::string exceptionStack = exception->Get(vm, StringRef::NewFromUtf8(vm, "stack"))->ToString(vm)->ToString(vm); GTEST_LOG_(INFO) << log << " exception name : " << exceptionName; GTEST_LOG_(INFO) << log << " exception message : " << exceptionMessage; GTEST_LOG_(INFO) << log << " exception stack : " << exceptionStack; tryCatch.Rethrow(); }; /* demo12 异常的抛出和处理 */ HWTEST_F_L0(JSNApiSampleTest, sample_demo12_exception_test) { GTEST_LOG_(INFO) << "sample_demo12_exception_test ======================================="; LocalScope scope(vm_); // Error Local exception1 = ThrowErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception1->IsUndefined()) { ClearAndPrintException4JSNApi(vm_, "ThrowErrorFuncTest"); } // RangeError Local exception2 = ThrowRangeErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception2->IsUndefined()) { ClearAndPrintException4TryCatch1(vm_, "ThrowRangeErrorFuncTest"); } // ReferenceError Local exception3 = ThrowReferenceErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception3->IsUndefined()) { ClearAndPrintException4TryCatch2(vm_, "ThrowReferenceErrorFuncTest"); } // SyntaxError Local exception4 = ThrowSyntaxErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception4->IsUndefined()) { PrintAndRethrowException4TryCatch3(vm_, "ThrowSyntaxErrorFuncTest"); ClearAndPrintException4TryCatch1(vm_, "ThrowSyntaxErrorFuncTest"); } // TypeError Local exception5 = ThrowTypeErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception5->IsUndefined()) { ClearAndPrintException4TryCatch1(vm_, "ThrowTypeErrorFuncTest"); } // AggregateError Local exception6 = ThrowAggregateErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception6->IsUndefined()) { ClearAndPrintException4TryCatch1(vm_, "ThrowAggregateErrorFuncTest"); } // EvalError Local exception7 = ThrowEvalErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception7->IsUndefined()) { ClearAndPrintException4TryCatch1(vm_, "ThrowEvalErrorFuncTest"); } // OOMError Local exception8 = ThrowOOMErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception8->IsUndefined()) { ClearAndPrintException4TryCatch1(vm_, "ThrowOOMErrorFuncTest"); } // TerminationError Local exception9 = ThrowTerminationErrorFuncTest(vm_, NumberRef::New(vm_, 0)); if (exception9->IsUndefined()) { ClearAndPrintException4TryCatch1(vm_, "ThrowTerminationErrorFuncTest"); } GTEST_LOG_(INFO) << "sample_demo12_exception_test ======================================="; } }