From 5418b66b68ffedc3a08578b7278938a1aa40ba8c Mon Sep 17 00:00:00 2001 From: etkmao Date: Tue, 22 Oct 2024 20:36:38 +0800 Subject: [PATCH 1/2] fix(core): static destruct crash in main thread for ios (#4085) When app exits, child thread may access the destructed global static object, which causing a crash --- dom/src/dom/taitank_layout_node.cc | 4 ++-- driver/js/src/napi/jsc/jsc_ctx.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dom/src/dom/taitank_layout_node.cc b/dom/src/dom/taitank_layout_node.cc index cd9f1766fcd..05726b7aed6 100644 --- a/dom/src/dom/taitank_layout_node.cc +++ b/dom/src/dom/taitank_layout_node.cc @@ -98,7 +98,7 @@ class TaitankLayoutConsts { {"inherit", DIRECTION_INHERIT}, {"ltr", DIRECTION_LTR}, {"rtl", DIRECTION_RTL}}; }; -static std::shared_ptr global_layout_consts = nullptr; +static TaitankLayoutConsts* global_layout_consts = nullptr; #define TAITANK_GET_STYLE_DECL(NAME, TYPE, DEFAULT) \ static TYPE GetStyle##NAME(const std::string& key) { \ @@ -823,7 +823,7 @@ void TaitankLayoutNode::Deallocate() { void InitLayoutConsts() { if (global_layout_consts == nullptr) { - global_layout_consts = std::make_shared(); + global_layout_consts = new TaitankLayoutConsts(); } } diff --git a/driver/js/src/napi/jsc/jsc_ctx.cc b/driver/js/src/napi/jsc/jsc_ctx.cc index 51152479073..cff6d1626df 100644 --- a/driver/js/src/napi/jsc/jsc_ctx.cc +++ b/driver/js/src/napi/jsc/jsc_ctx.cc @@ -49,13 +49,13 @@ constexpr char16_t kSetStr[] = u"set"; static std::once_flag global_class_flag; static JSClassRef global_class; -static std::shared_ptr global_constructor_data_mgr = nullptr; +static ConstructorDataManager* global_constructor_data_mgr = nullptr; JSCCtx::JSCCtx(JSContextGroupRef group, std::weak_ptr vm): vm_(vm) { std::call_once(global_class_flag, []() { JSClassDefinition global = kJSClassDefinitionEmpty; global_class = JSClassCreate(&global); - global_constructor_data_mgr = std::make_shared(); + global_constructor_data_mgr = new ConstructorDataManager(); }); context_ = JSGlobalContextCreateInGroup(group, global_class); From 1308af2ba2aaa57e982f6bc3fb77cbad69ba737b Mon Sep 17 00:00:00 2001 From: zealotchen Date: Wed, 23 Oct 2024 11:07:03 +0800 Subject: [PATCH 2/2] fix(web): fix webrender not show when length is 1 --- .../src/third-lib/size-position-manager.js | 61 ++++++++----------- .../src/third-lib/virtual-list.js | 2 +- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/driver/js/packages/hippy-web-renderer/src/third-lib/size-position-manager.js b/driver/js/packages/hippy-web-renderer/src/third-lib/size-position-manager.js index 12f2b08f31b..ddc01e6c990 100644 --- a/driver/js/packages/hippy-web-renderer/src/third-lib/size-position-manager.js +++ b/driver/js/packages/hippy-web-renderer/src/third-lib/size-position-manager.js @@ -24,7 +24,7 @@ export const ALIGN_START = 'start'; export const ALIGN_CENTER = 'center'; export const ALIGN_END = 'end'; -export default class SizePositionManager { +export default class SizeAndPositionManager { constructor({ itemCount, itemSizeGetter, @@ -50,24 +50,17 @@ export default class SizePositionManager { * It just-in-time calculates (or used cached values) for items leading up to the index. */ getSizeAndPositionForIndex(index) { - if (index < 0) { + if (index < 0 || index >= this._itemCount) { throw Error(`Requested index ${index} is outside of range 0..${this._itemCount}`); } - if(index === 0 && this._itemCount===0){ - return 0; - } - if (index >= this._itemCount && this._itemCount!==0) { - index = this._itemCount - 1; - } - if (index > this._lastMeasuredIndex) { - let lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem(); - let offset = lastMeasuredSizeAndPosition.offset + - lastMeasuredSizeAndPosition.size; + const lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem(); + let offset = lastMeasuredSizeAndPosition.offset + + lastMeasuredSizeAndPosition.size; for (let i = this._lastMeasuredIndex + 1; i <= index; i++) { - let size = this._itemSizeGetter({index: i}); + const size = this._itemSizeGetter({ index: i }); if (size == null || isNaN(size)) { throw Error(`Invalid size returned for index ${i} of value ${size}`); @@ -90,7 +83,7 @@ export default class SizePositionManager { getSizeAndPositionOfLastMeasuredItem() { return this._lastMeasuredIndex >= 0 ? this._itemSizeAndPositionData[this._lastMeasuredIndex] - : {offset: 0, size: 0}; + : { offset: 0, size: 0 }; } /** @@ -100,9 +93,7 @@ export default class SizePositionManager { */ getTotalSize() { const lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem(); - if(this._lastMeasuredIndex === this._itemCount){ - return lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size; - } + return lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size + (this._itemCount - this._lastMeasuredIndex - 1) * this._estimatedItemSize; } @@ -111,7 +102,6 @@ export default class SizePositionManager { * * @param align Desired alignment within container; one of "start" (default), "center", or "end" * @param containerSize Size (width or height) of the container viewport - * @param targetIndex index target item * @return Offset to use to ensure the specified item is visible */ getUpdatedOffsetForIndex({ @@ -146,11 +136,11 @@ export default class SizePositionManager { return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); } - getVisibleRange({containerSize, offset, overScanCount}) { + getVisibleRange({ containerSize, offset, overscanCount }) { const totalSize = this.getTotalSize(); if (totalSize === 0) { - return {start:0,stop:0}; + return {}; } const maxOffset = offset + containerSize; @@ -165,9 +155,9 @@ export default class SizePositionManager { offset += this.getSizeAndPositionForIndex(stop).size; } - if (overScanCount) { - start = Math.max(0, start - overScanCount); - stop = Math.min(stop + overScanCount, this._itemCount-1); + if (overscanCount) { + start = Math.max(0, start - overscanCount); + stop = Math.min(stop + overscanCount, this._itemCount); } return { @@ -185,7 +175,7 @@ export default class SizePositionManager { this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); } - _binarySearch({low, high, offset}) { + _binarySearch({ low, high, offset }) { let middle; let currentOffset; @@ -195,7 +185,7 @@ export default class SizePositionManager { if (currentOffset === offset) { return middle; - } else if (currentOffset < offset) { + } if (currentOffset < offset) { low = middle + 1; } else if (currentOffset > offset) { high = middle - 1; @@ -207,12 +197,12 @@ export default class SizePositionManager { } } - _exponentialSearch({index, offset}) { + _exponentialSearch({ index, offset }) { let interval = 1; while ( - index < this._itemCount && - this.getSizeAndPositionForIndex(index).offset < offset + index < this._itemCount + && this.getSizeAndPositionForIndex(index).offset < offset ) { index += interval; interval *= 2; @@ -250,14 +240,13 @@ export default class SizePositionManager { low: 0, offset, }); - } else { - // If we haven't yet measured this high, fallback to an exponential search with an inner binary search. - // The exponential search avoids pre-computing sizes for the full set of items as a binary search would. - // The overall complexity for this approach is O(log n). - return this._exponentialSearch({ - index: lastMeasuredIndex, - offset, - }); } + // If we haven't yet measured this high, fallback to an exponential search with an inner binary search. + // The exponential search avoids pre-computing sizes for the full set of items as a binary search would. + // The overall complexity for this approach is O(log n). + return this._exponentialSearch({ + index: lastMeasuredIndex, + offset, + }); } } diff --git a/driver/js/packages/hippy-web-renderer/src/third-lib/virtual-list.js b/driver/js/packages/hippy-web-renderer/src/third-lib/virtual-list.js index 356cd1ba59a..f79ef38d06c 100644 --- a/driver/js/packages/hippy-web-renderer/src/third-lib/virtual-list.js +++ b/driver/js/packages/hippy-web-renderer/src/third-lib/virtual-list.js @@ -173,7 +173,7 @@ export class VirtualizedList { }); const fragment = document.createDocumentFragment(); - for (let index = start; index <= stop&&stop>0; index++) { + for (let index = start; index <= stop; index++) { fragment.appendChild(renderRow(index)); }