From 32718edbfffd714a1f587a4d22e84efe33588d02 Mon Sep 17 00:00:00 2001 From: birdswu Date: Wed, 28 May 2025 16:57:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E8=AF=86=E9=94=99=E8=AF=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20=20xiaoliang?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circular.json5} | 30 ++----- .../ets/pages/CircularDependencies/index.ets | 12 +++ .../ets/pages/CircularDependencies/page.ets | 13 +++ .../entry/src/main/ets/pages/ClassObjName.ets | 44 +++++++++++ ArkTS/entry/src/main/ets/pages/DemoModule.cpp | 31 ++++++++ ArkTS/entry/src/main/ets/pages/KeyObject.ets | 2 +- .../entryability/EntryAbilityOnDisplay.ets | 79 +++++++++++++++++++ .../entryability/EntryAbilityOnDisplay2.ets | 74 +++++++++++++++++ .../src/main/ets/entryability/Rotation.json5 | 17 ++++ .../main/ets/entryability/auto_rotation.json5 | 47 +++++++++++ .../src/main/ets/pages/CustomizeTabs.ets | 2 +- .../entry/src/main/ets/pages/MixContent.ets | 17 +--- .../main/ets/pages/OnlyOnTheFirstTrigger.ets | 25 ++++-- CameraKit/entry/src/main/module.json5 | 2 +- .../main/ets/pages/SaveWebPictureToAlbum.ets | 4 +- .../entry/src/main/cpp/Js_MemoryException.cpp | 47 +++++++++++ .../src/main/cpp/Jsvm_CallbackStruct.cpp | 21 +++++ .../src/main/cpp/Jsvm_CallbackStruct2.cpp | 19 +++++ .../src/main/cpp/Jsvm_CallbackStruct3.cpp | 22 ++++++ Jsvm/entry/src/main/cpp/Jsvm_Selfcheck.cpp | 23 ++++++ Jsvm/entry/src/main/cpp/Jsvm_test.cpp | 18 ++--- Jsvm/entry/src/main/cpp/MemoryException.log | 16 ++++ .../entry/src/main/ets/cpp/MGDolphinTOTP.h | 6 +- 23 files changed, 511 insertions(+), 60 deletions(-) rename ArkTS/entry/src/main/ets/pages/{CircularDependencies.txt => CircularDependencies/circular.json5} (34%) create mode 100644 ArkTS/entry/src/main/ets/pages/CircularDependencies/index.ets create mode 100644 ArkTS/entry/src/main/ets/pages/CircularDependencies/page.ets create mode 100644 ArkTS/entry/src/main/ets/pages/ClassObjName.ets create mode 100644 ArkTS/entry/src/main/ets/pages/DemoModule.cpp create mode 100644 ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay.ets create mode 100644 ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay2.ets create mode 100644 ArkUI/entry/src/main/ets/entryability/Rotation.json5 create mode 100644 ArkUI/entry/src/main/ets/entryability/auto_rotation.json5 create mode 100644 Jsvm/entry/src/main/cpp/Js_MemoryException.cpp create mode 100644 Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct.cpp create mode 100644 Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct2.cpp create mode 100644 Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct3.cpp create mode 100644 Jsvm/entry/src/main/cpp/Jsvm_Selfcheck.cpp create mode 100644 Jsvm/entry/src/main/cpp/MemoryException.log diff --git a/ArkTS/entry/src/main/ets/pages/CircularDependencies.txt b/ArkTS/entry/src/main/ets/pages/CircularDependencies/circular.json5 similarity index 34% rename from ArkTS/entry/src/main/ets/pages/CircularDependencies.txt rename to ArkTS/entry/src/main/ets/pages/CircularDependencies/circular.json5 index 6c04d6f..2d8f183 100644 --- a/ArkTS/entry/src/main/ets/pages/CircularDependencies.txt +++ b/ArkTS/entry/src/main/ets/pages/CircularDependencies/circular.json5 @@ -2,33 +2,15 @@ * FAQ:模块间循环依赖导致运行时未初始化异常问题定位 */ -// [Start CircularDependencies] -// index.ets -import { bar } from './page' - -export function foo() { - bar() -} - -// page.ets -import { foo } from './index' - -export function bar() { - foo() -} -bar() -// [End CircularDependencies] - - -// [Start CircularDependencies2] +// [Start CircularDependencies3] { "files": [ // A glob pattern array used to represent the file range applicable to the configuration. - "**/*.js", - "**/*.ts", - "**/*.ets" + "**/*.js", + "**/*.ts", + "**/*.ets" ], "rules": { - "@security/no-cycle": "error" // Configure circular dependency check rules. + "@security/no-cycle": "error" // Configure circular dependency check rules. } } -// [End CircularDependencies2] \ No newline at end of file +// [End CircularDependencies3] diff --git a/ArkTS/entry/src/main/ets/pages/CircularDependencies/index.ets b/ArkTS/entry/src/main/ets/pages/CircularDependencies/index.ets new file mode 100644 index 0000000..ee7155c --- /dev/null +++ b/ArkTS/entry/src/main/ets/pages/CircularDependencies/index.ets @@ -0,0 +1,12 @@ +/* +* FAQ:模块间循环依赖导致运行时未初始化异常问题定位 +*/ + +// [Start CircularDependencies1] +// index.ets +import { bar } from './page' + +export function foo() { + bar() +} +// [End CircularDependencies1] diff --git a/ArkTS/entry/src/main/ets/pages/CircularDependencies/page.ets b/ArkTS/entry/src/main/ets/pages/CircularDependencies/page.ets new file mode 100644 index 0000000..de12f05 --- /dev/null +++ b/ArkTS/entry/src/main/ets/pages/CircularDependencies/page.ets @@ -0,0 +1,13 @@ +/* +* FAQ:模块间循环依赖导致运行时未初始化异常问题定位 +*/ + +// [Start CircularDependencies2] +// page.ets +import { foo } from './index' + +export function bar() { + foo() +} +bar() +// [End CircularDependencies2] diff --git a/ArkTS/entry/src/main/ets/pages/ClassObjName.ets b/ArkTS/entry/src/main/ets/pages/ClassObjName.ets new file mode 100644 index 0000000..9f4163d --- /dev/null +++ b/ArkTS/entry/src/main/ets/pages/ClassObjName.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取对象的类名 +*/ + +// [Start ClassObjName] +class TestClass { + a: string = 'A'; + b: string = 'B'; +} + +let testClassObj: TestClass = new TestClass(); + +@Entry +@Component +struct Index { + build() { + Row() { + Column() { + Button('get Class Name') + .onClick(() => { + console.log('TestClass Name:', testClassObj.constructor.name); + }) + } + .width('100%') + } + .height('100%') + } +} +// [End ClassObjName] \ No newline at end of file diff --git a/ArkTS/entry/src/main/ets/pages/DemoModule.cpp b/ArkTS/entry/src/main/ets/pages/DemoModule.cpp new file mode 100644 index 0000000..b55d682 --- /dev/null +++ b/ArkTS/entry/src/main/ets/pages/DemoModule.cpp @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:ModuleManager模块加载流程是什么样的? +*/ + +// [Start demoModule] +static napi_module demoModule = { + .nm_version = 1, // nm版本号,默认值为1,类型为int + .nm_flags = 0, // nm标识符,类型为unsigned int + .nm_filename = nullptr, // 文件名,暂不关注,使用默认值即可,类型为char* + .nm_register_func = Init, // 指定nm的入口函数,类型为napi_addon_register_func + .nm_modname = "entry", // 指定TS页面导入的模块名,类型为char* + .nm_priv = ((void*)0), // 暂不关注,使用默认即可,类型为void* + .reserved = { 0 } // 暂不关注,使用默认值即可,类型为void* +}; +// [End demoModule] + diff --git a/ArkTS/entry/src/main/ets/pages/KeyObject.ets b/ArkTS/entry/src/main/ets/pages/KeyObject.ets index e1555c2..7ce3e63 100644 --- a/ArkTS/entry/src/main/ets/pages/KeyObject.ets +++ b/ArkTS/entry/src/main/ets/pages/KeyObject.ets @@ -17,7 +17,7 @@ * FAQ:如何通过key获取对象值 */ -// [Start key_object ] +// [Start key_object] class Student { data: Record = { 'name': 'aaa', 'age': 'bbb' }; } diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay.ets new file mode 100644 index 0000000..14c67b9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay.ets @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在display.on('change')监听回调中,无法使用Window实例获取更新后的窗口大小 +*/ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { display, window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + AppStorage.setOrCreate('windowStage',windowStage); + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + const context = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate("context", context); + }); + + // [Start EntryAbilityOnDisplay] + // Display update first + display.on('change', async (data) => { + let newDisplay: display.Display = display.getDefaultDisplaySync(); + console.info('Orientation: ' + newDisplay.orientation); + let windowClass: window.Window = await window.getLastWindow(this.context); + // After updating the window, the original width and height are still obtained + let windowProperties = windowClass.getWindowProperties(); + console.info('Width: ' + windowProperties.windowRect.width + + ', height: ' + windowProperties.windowRect.height); + // Please ensure that the relevant Window instance, namely windowClass, has been obtained + windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_CUTOUT); + }); + // [End EntryAbilityOnDisplay] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay2.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay2.ets new file mode 100644 index 0000000..e073aea --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOnDisplay2.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在display.on('change')监听回调中,无法使用Window实例获取更新后的窗口大小 +*/ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { display, window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + AppStorage.setOrCreate('windowStage',windowStage); + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + const context = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate("context", context); + }); + + // [Start EntryAbilityOnDisplay2] + display.on('change', (data) => { + console.info('Succeeded in enabling the listener for display changes. Data: ' + + JSON.stringify(data)); + let newDisplay: display.Display = display.getDefaultDisplaySync(); + console.info('Orientation: ' + newDisplay.orientation + 'width: ' + + newDisplay.width + ', height: ' + newDisplay.height); + }); + // [End EntryAbilityOnDisplay2] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/Rotation.json5 b/ArkUI/entry/src/main/ets/entryability/Rotation.json5 new file mode 100644 index 0000000..a253b00 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/Rotation.json5 @@ -0,0 +1,17 @@ +/* +* FAQ:如何实现折叠屏折叠态不适配旋转,展示态适配旋转 +*/ + +// [Start entry_ability_display_adaptation_rotation2] +// module.json5 +{ + "module": { + "abilities": [ + { + "name": "EntryAbility", + "orientation":"unspecified" // 未定义方向模式,由系统判定 + } + ] + } +} +// [End entry_ability_display_adaptation_rotation2] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/auto_rotation.json5 b/ArkUI/entry/src/main/ets/entryability/auto_rotation.json5 new file mode 100644 index 0000000..1a6cb72 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/auto_rotation.json5 @@ -0,0 +1,47 @@ +/* +* FAQ:如何实现应用的屏幕自动旋转 +*/ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + // [Start auto_rotation] + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "auto_rotation", // Rotate with the sensor + } + ], + // [End auto_rotation] + "requestPermissions": [ + ] + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets b/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets index 0643fbf..b2703a6 100644 --- a/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets +++ b/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets @@ -94,4 +94,4 @@ struct CustomizeTheTabsBarAndItsAlignment { .height('100%') } } -// [end customize_tabs] \ No newline at end of file +// [End customize_tabs] \ No newline at end of file diff --git a/ArkWebKit/entry/src/main/ets/pages/MixContent.ets b/ArkWebKit/entry/src/main/ets/pages/MixContent.ets index 7172b18..0056752 100644 --- a/ArkWebKit/entry/src/main/ets/pages/MixContent.ets +++ b/ArkWebKit/entry/src/main/ets/pages/MixContent.ets @@ -18,27 +18,18 @@ */ // [Start MixContent] +// xxx.ets import { webview } from '@kit.ArkWeb'; -import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component -export struct WebUserAgent { +struct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); - + @State mode: MixedMode = MixedMode.All; build() { Column() { - Button('getUserAgent') - .onClick(() => { - try { - let userAgent = this.controller.getUserAgent(); - console.log("userAgent: " + userAgent); - } catch (error) { - let e: BusinessError = error as BusinessError; - console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); - } - }) Web({ src: 'www.example.com', controller: this.controller }) + .mixedMode(this.mode) } } } diff --git a/ArkWebKit/entry/src/main/ets/pages/OnlyOnTheFirstTrigger.ets b/ArkWebKit/entry/src/main/ets/pages/OnlyOnTheFirstTrigger.ets index 8f84e35..f51ea5c 100644 --- a/ArkWebKit/entry/src/main/ets/pages/OnlyOnTheFirstTrigger.ets +++ b/ArkWebKit/entry/src/main/ets/pages/OnlyOnTheFirstTrigger.ets @@ -18,22 +18,31 @@ */ // [Start OnlyOnTheFirstTrigger] -import { webview } from '@kit.ArkWeb' - -webview.once("webInited", () => { - console.log("setCookie"); - webview.WebCookieManager.configCookie("https://www.example.com", 'a=b,c=d,e=f'); -}) +import { webview } from '@kit.ArkWeb'; @Entry @Component -struct WebComponent { +struct OnlyOnTheFirstTrigger { controller: webview.WebviewController = new webview.WebviewController(); + isFirst: boolean = false; build() { Column() { - Web({ src: 'www.example.com', controller: this.controller }) + Web({ + src: 'www.example.com', controller: this.controller + }) + .onAppear(() => { + this.isFirst = true; + }) + .onPageBegin(() => { + if (this.isFirst) { + this.isFirst = false; + console.info('test isFirst'); + } + }) } + .width('100%') + .height('100%') } } // [End OnlyOnTheFirstTrigger] \ No newline at end of file diff --git a/CameraKit/entry/src/main/module.json5 b/CameraKit/entry/src/main/module.json5 index be1e373..1e4a3e7 100644 --- a/CameraKit/entry/src/main/module.json5 +++ b/CameraKit/entry/src/main/module.json5 @@ -95,6 +95,6 @@ "reason": "$string:Camera_Permission_Request" } ], - // [End ResolvePreviewStreamBlackScreenIssue_Permission] + // [End ResolvePreviewStreamBlackScreenIssue_Permissions] } } \ No newline at end of file diff --git a/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets b/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets index 4ac93bb..4f54170 100644 --- a/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets +++ b/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets @@ -86,8 +86,10 @@ struct SaveImage { } }).catch((error: BusinessError) => { console.error('Failed to pack the image. And the error is: ' + error); + }).finally(()=>{ + pixelMap.release(); }) - pixelMap.release(); + }) } } diff --git a/Jsvm/entry/src/main/cpp/Js_MemoryException.cpp b/Jsvm/entry/src/main/cpp/Js_MemoryException.cpp new file mode 100644 index 0000000..58a8bba --- /dev/null +++ b/Jsvm/entry/src/main/cpp/Js_MemoryException.cpp @@ -0,0 +1,47 @@ +/* +* FAQ:如何解决应用运行时OH_JSVM_CreateVM多线程创建发生竞争,导致VM内部的成员变量(array_buffer_allocator_)内存异常应用退出问题 +*/ + +// [Start Js_MemoryException2] +std::unique_ptr BackingStore::Allocate( + Isolate* isolate, size_t byte_length, SharedFlag shared, + InitializedFlag initialized) { + ... + auto allocator = isolate->array_buffer_allocator(); + ... + auto allocate_buffer = [allocator, initialized](size_t byte_length) { + if (initialized == InitializedFlag::kUninitialized) { + return allocator->AllocateUninitialized(byte_length); + } + void* buffer_start = allocator->Allocate(byte_length); + if (buffer_start) { + // TODO(wasm): node does not implement the zero-initialization API. + // Reenable this debug check when node does implement it properly. + constexpr bool + kDebugCheckZeroDisabledDueToNodeNotImplementingZeroInitAPI = true; + if ((!(kDebugCheckZeroDisabledDueToNodeNotImplementingZeroInitAPI)) && + !v8_flags.mock_arraybuffer_allocator) { + DebugCheckZero(buffer_start, byte_length); + } + } + return buffer_start; + }; + buffer_start = isolate->heap()->AllocateExternalBackingStore( + allocate_buffer, byte_length); + ... +} +// [End Js_MemoryException2] + +// [Start Js_MemoryException3] +// Create an instance of JSVM. +const JSVM_CreateVMOptions* options = new JSVM_CreateVMOptions(); +JSVM_Status res = USVM_OK; +{ + std::Lock_guard Lock(create_jsym_mutex_); + res = OH_JSVM_CreateVM(options, &vm_); +} +if (res != JSVN_OK vm_ == nullptr) { + XLOG(ERROR) << "JSVM create vm failed"; +} +// When we start, open vm scope. +// [End Js_MemoryException3] \ No newline at end of file diff --git a/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct.cpp b/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct.cpp new file mode 100644 index 0000000..1046ee9 --- /dev/null +++ b/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct.cpp @@ -0,0 +1,21 @@ +/* +* FAQ:如何管理JSVM_CallbackStruct生命周期 +*/ + +// [Start Jsvm_CallbackStruct] +JSVM_Value CreateFunction(JSVM_Env env) { + JSVM_CallbackStruct callbackStruct; + callbackStruct.data = nullptr; + callbackStruct.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value { + return nullptr; + }; + + JSVM_Value result = nullptr; + OH_JSVM_CreateFunction(env, "foo", JSVM_AUTO_LENGTH, &callbackStruct, &result); + return result; +} +void SomeFunction() { + char stack[] = "hello world"; +} +// [End Jsvm_CallbackStruct] + diff --git a/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct2.cpp b/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct2.cpp new file mode 100644 index 0000000..423aaa1 --- /dev/null +++ b/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct2.cpp @@ -0,0 +1,19 @@ +/* +* FAQ:如何管理JSVM_CallbackStruct生命周期 +*/ + +// [Start Jsvm_CallbackStruct2] +// ... + +auto func = CreateFunction(env); +SomeFunction(); + +JSVM_Value undef = nullptr; +OH_JSVM_GetUndefined(env, &undef); + +JSVM_Value result; +OH_JSVM_CallFunction(env, undef, func, 0, nullptr, &result); + +// ... +// [End Jsvm_CallbackStruct2] + diff --git a/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct3.cpp b/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct3.cpp new file mode 100644 index 0000000..714ff75 --- /dev/null +++ b/Jsvm/entry/src/main/cpp/Jsvm_CallbackStruct3.cpp @@ -0,0 +1,22 @@ +/* +* FAQ:如何管理JSVM_CallbackStruct生命周期 +*/ + +// [Start Jsvm_CallbackStruct3] +JSVM_Value CreateFunction(JSVM_Env env) { + JSVM_Callback cb = new JSVM_CallbackStruct; + cb->data = nullptr; + cb->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value { return nullptr; }; + + JSVM_Value result = nullptr; + OH_JSVM_CreateFunction(env, "foo", JSVM_AUTO_LENGTH, cb, &result); + OH_JSVM_AddFinalizer( + env, result, reinterpret_cast(cb), + [](JSVM_Env env, void *data, void *hint) -> void { + delete static_cast(data); + }, nullptr, nullptr); + + return result; +} +// [End Jsvm_CallbackStruct3] + diff --git a/Jsvm/entry/src/main/cpp/Jsvm_Selfcheck.cpp b/Jsvm/entry/src/main/cpp/Jsvm_Selfcheck.cpp new file mode 100644 index 0000000..7cd3b40 --- /dev/null +++ b/Jsvm/entry/src/main/cpp/Jsvm_Selfcheck.cpp @@ -0,0 +1,23 @@ +/* +* FAQ:如何自排查OOM(v8::FatalProcessOutOfMemory)错误 +*/ + +// [Start Jsvm_Selfcheck] +// ... +JSVM_InitOptions init_options; +init_options.argc = (int*)malloc(sizeof(int)); +*init_options.argc = 3; +init_options.argv = (char**)malloc(3 * sizeof(char*)); +init_options.argv[1] = "--max-semi-space-size=1024"; +init_options.argv[2] = "--max-old-space-size=1024"; +init_options.removeFlags = true; +init_options.externalReferences = nullptr; + +JSVM_Status status = OH_JSVM_Init(&init_options); + +if (status != JSVM_OK) { + // If the status is not JSVM-OK, it indicates that OH_JSVM_Snit execution failed and init_options was not successfully set. +} +// ... +// [End Jsvm_Selfcheck] + diff --git a/Jsvm/entry/src/main/cpp/Jsvm_test.cpp b/Jsvm/entry/src/main/cpp/Jsvm_test.cpp index 0276819..e6ed106 100644 --- a/Jsvm/entry/src/main/cpp/Jsvm_test.cpp +++ b/Jsvm/entry/src/main/cpp/Jsvm_test.cpp @@ -9,7 +9,7 @@ #include "ark_runtime/jsvm.h" #include -//[Start jsvm_init] +// [Start jsvm_init] #include "jsvm_types.h" #include "jsvm.h" @@ -25,17 +25,17 @@ int main() { Init(nullptr); Init(nullptr); } -//[End jsvm_init] +// [End jsvm_init] -//[Start get_value_string_utf8] +// [Start get_value_string_utf8] JSVM_EXTERN JSVM_Status OH_JSVM_GetValueStringUtf8(JSVM_Env env, JSVM_Value value, char* buf, size_t bufsize, size_t* result); -//[End get_value_string_utf8] +// [End get_value_string_utf8] -//[Start get_value_string] +// [Start get_value_string] std::string GetValueString(JSVM_Env env, JSVM_Value value) { constexpr size_t PREALLOC_SIZE = 256; char preallocMemory[PREALLOC_SIZE]; @@ -43,17 +43,17 @@ std::string GetValueString(JSVM_Env env, JSVM_Value value) { char *buff = preallocMemory; - // 获取长度 + // Obtain length size_t totalLen = 0; OH_JSVM_GetValueStringUtf8(env, value, nullptr, 0, &totalLen); size_t needed = totalLen + 1; if (needed > PREALLOC_SIZE) { - // 分配空间,大小需包含终止字符 + // Allocate space, size must include termination character buff = new char[needed]; } - // 获取字符串 + // get string OH_JSVM_GetValueStringUtf8(env, value, buff, needed, nullptr); @@ -65,4 +65,4 @@ std::string GetValueString(JSVM_Env env, JSVM_Value value) { } return ret; } -//[End get_value_string] +// [End get_value_string] diff --git a/Jsvm/entry/src/main/cpp/MemoryException.log b/Jsvm/entry/src/main/cpp/MemoryException.log new file mode 100644 index 0000000..b5c1a61 --- /dev/null +++ b/Jsvm/entry/src/main/cpp/MemoryException.log @@ -0,0 +1,16 @@ +/* +* FAQ:如何解决应用运行时OH_JSVM_CreateVM多线程创建发生竞争,导致VM内部的成员变量(array_buffer_allocator_)内存异常应用退出问题 +*/ + +// [Start Js_MemoryException1] +#00 pc 00000000017793f8 /system/lib64/ndk/libjsvm.so +#01 pc 000000000163cef4 /system/lib64/ndk/libjsvm.so(v8::internal::Heap::AllocateExternalBackingStore(std::__h::function const&, unsigned long)+212) +#02 pc 0000000001777454 /system/lib64/ndk/libjsvm.so(v8::internal::BackingStore::Allocate(v8::internal::Isolate*, unsigned long, v8::internal::SharedFlag, v8::internal::InitializedFlag)+220) +#03 pc 000000000149e420 /system/lib64/ndk/libjsvm.so +#04 pc 000000000149d99c /system/lib64/ndk/libjsvm.so(v8::internal::Builtin_ArrayBufferConstructor(int, unsigned long*, v8::internal::Isolate*)+260) +#05 pc 0000000000f75984 /system/lib64/ndk/libjsvm.so(Builtins_CEntry_Return1_ArgvOnStack_BuiltinExit+100) +#06 pc 0000000000ee6e40 /system/lib64/ndk/libjsvm.so(Builtins_JSBuiltinsConstructStub+320) +#07 pc 000000000102eae4 /system/lib64/ndk/libjsvm.so(Builtins_ConstructHandler+644) +#08 pc 0000000000ee9b88 /system/lib64/ndk/libjsvm.so(Builtins_InterpreterEntryTrampoline+264) +#09 pc 0000000000ee9b88 /system/lib64/ndk/libjsvm.so(Builtins_InterpreterEntryTrampoline+264) +// [End Js_MemoryException1] \ No newline at end of file diff --git a/ProjectManagement/entry/src/main/ets/cpp/MGDolphinTOTP.h b/ProjectManagement/entry/src/main/ets/cpp/MGDolphinTOTP.h index 64b902a..064d8c0 100644 --- a/ProjectManagement/entry/src/main/ets/cpp/MGDolphinTOTP.h +++ b/ProjectManagement/entry/src/main/ets/cpp/MGDolphinTOTP.h @@ -4,7 +4,7 @@ // Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, // please include "napi/native_api.h". //FAQ:.h文件中uint8_t无法使用如何解决? -//[Start uint8_t] +// [Start uint8_t] #ifdef __cplusplus extern “C” { #endif @@ -12,4 +12,6 @@ extern “C” { #include “MGDolphinTOTPsha1.h” #ifdef __cplusplus} #endif -//[End uint8_t] +// [End uint8_t] + + -- Gitee