From 1822dfb49eb36615321560ad843afa3f53bb5fd2 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 13 Nov 2024 16:14:30 +0100 Subject: [PATCH] Tweak the lookup code. Add some "prefer-inline" annotations. --- .../lib/src/grapheme_clusters/table.dart | 16 ++++++++--- pkgs/characters/test/breaks_test.dart | 3 +-- pkgs/characters/test/src/unicode_tests.dart | 7 ++--- pkgs/characters/tool/bin/generate_tables.dart | 27 ++++++++++--------- .../tool/src/automaton_builder.dart | 7 +++++ 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/pkgs/characters/lib/src/grapheme_clusters/table.dart b/pkgs/characters/lib/src/grapheme_clusters/table.dart index ed0ae3b8..fce9c85a 100644 --- a/pkgs/characters/lib/src/grapheme_clusters/table.dart +++ b/pkgs/characters/lib/src/grapheme_clusters/table.dart @@ -1126,7 +1126,6 @@ const String _start = '\u1132\u166c\u166c\u206f\u11c0\u13fb\u166c\u166c\u166c' '\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c' '\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c\u166c' '\u166c\u166c'; - @pragma('dart2js:prefer-inline') @pragma('vm:prefer-inline') @pragma('wasm:prefer-inline') @@ -1136,10 +1135,13 @@ int low(int codeUnit) { return _data.codeUnitAt(index); } +@pragma('dart2js:prefer-inline') +@pragma('vm:prefer-inline') +@pragma('wasm:prefer-inline') int high(int lead, int tail) { - var offset = ((0x3ff & lead) << 10) | (0x3ff & tail); - var chunkStart = _start.codeUnitAt(2048 + (offset >> 8)); - var index = chunkStart + (offset & 255); + var offset = (((0x3ff & lead) << 10) + (0x3ff & tail)) + (2048 << 8); + var chunkStart = _start.codeUnitAt(offset >> 8); + var index = chunkStart + (tail & 255); return _data.codeUnitAt(index); } @@ -1155,6 +1157,9 @@ const _stateMachine = '\x15\x01)))µ\x8d\x01=QeyeyÉ)))ñð\x15\x01)))µ\x8d\x00 '\x15\x01)((µ\x8d\x01=QeyeyĮƐƐƤñð\x15\x01)((µ\x8d\x01=QeyeyłƤƤƤñð\x15\x01)Ƹ' '(µ\x8d\x01=QeyeyÉnjƸƸñð\x15\x01)((µĚ\x01=QeyeyÉ(((ñð\x15\x01)((Ŗ\x8d\x01=Qe' 'yeyÉ(((ñð'; +@pragma('dart2js:prefer-inline') +@pragma('vm:prefer-inline') +@pragma('wasm:prefer-inline') int move(int state, int inputCategory) => _stateMachine.codeUnitAt((state & -4) + inputCategory); @@ -1166,5 +1171,8 @@ const _backStateMachine = '\x01\x01)==µ\x8d\x15)QeyQQÉ===ñð\x00\x01)==µ\x8d ')==¡\x8d\x15(QeyQQÉ===ñð\x00\x00(<<´\x8c\x14(PdxPPÈ<<<ðð\x01\x01)==µ\x8d' '\x15)QeyQQÉ===ðð??)Ę=µ\x8c?)QeyQQÉ=ĘĘ?ð??)==µ\x8d?)QeyQQÉĬĬŀ?ð??)==µ\x8d?)' 'QeyQQÈŀŀŀ?ðÜÜÜÜÜŨÜÜÜÜÜÜÜÜÜÜÜÜÜ\x00¡¡¡¡¡Ŕ¡¡¡¡¡¡¡¡¡¡¡¡¡\x00'; +@pragma('dart2js:prefer-inline') +@pragma('vm:prefer-inline') +@pragma('wasm:prefer-inline') int moveBack(int state, int inputCategory) => _backStateMachine.codeUnitAt((state & -4) + inputCategory); diff --git a/pkgs/characters/test/breaks_test.dart b/pkgs/characters/test/breaks_test.dart index 3ee68ad7..d9e4b52e 100644 --- a/pkgs/characters/test/breaks_test.dart +++ b/pkgs/characters/test/breaks_test.dart @@ -412,9 +412,9 @@ List<(List parts, String kind)> testVariants(List parts) { lower.add([]); for (var rune in part.runes) { int category, runeLC = rune, runeFC = rune, runeUC = rune; + category = categoryOf(rune); if (rune < 0x10000) { runeLC = rune; - category = low(rune); var other = upperChars[category]; if (other >= 0) { changes |= hasNonBmp; @@ -422,7 +422,6 @@ List<(List parts, String kind)> testVariants(List parts) { } } else { runeUC = rune; - category = high((rune - 0x10000) >> 10, rune & 0x3FF); var other = lowerChars[category]; if (other >= 0) { changes |= hasBmp; diff --git a/pkgs/characters/test/src/unicode_tests.dart b/pkgs/characters/test/src/unicode_tests.dart index 167dea3e..5a38e6b5 100644 --- a/pkgs/characters/test/src/unicode_tests.dart +++ b/pkgs/characters/test/src/unicode_tests.dart @@ -26,9 +26,10 @@ String testDescription(List expected) { return "÷ $expectedString ÷"; } -int _category(int codePoint) { +int categoryOf(int codePoint) { if (codePoint < 0x10000) return low(codePoint); - return high((codePoint - 0x10000) >> 10, codePoint & 0x3ff); + var nonBmpOffset = codePoint - 0x10000; + return high(0xD800 + (nonBmpOffset >> 10), 0xDC00 + (nonBmpOffset & 0x3ff)); } String partCategories(List parts) { @@ -41,7 +42,7 @@ String partCategories(List parts) { return parts.map((part) { return part.runes - .map((n) => "#${posOf(n)}:${categoryLongNames[_category(n)]}") + .map((n) => "#${posOf(n)}:${categoryLongNames[categoryOf(n)]}") .join(" × "); }).join(" ÷ "); } diff --git a/pkgs/characters/tool/bin/generate_tables.dart b/pkgs/characters/tool/bin/generate_tables.dart index 314ead35..5a4b8485 100644 --- a/pkgs/characters/tool/bin/generate_tables.dart +++ b/pkgs/characters/tool/bin/generate_tables.dart @@ -244,10 +244,7 @@ void _writeSurrogateLookupFunction(StringSink out, String dataName, String _lookupMethod( String name, String dataName, String startName, int chunkSize) => """ - -@pragma('dart2js:prefer-inline') -@pragma('vm:prefer-inline') -@pragma('wasm:prefer-inline') +$preferInline int $name(int codeUnit) { var chunkStart = $startName.codeUnitAt(codeUnit >> ${chunkSize.bitLength - 1}); var index = chunkStart + (codeUnit & ${chunkSize - 1}); @@ -256,23 +253,29 @@ int $name(int codeUnit) { """; String _lookupSurrogatesMethod(String name, String dataName, String startName, - int startOffset, int chunkSize) => - chunkSize == 1024 - ? """ + int startOffset, int chunkSize) { + if (chunkSize == 1024) { + return """ +$preferInline int $name(int lead, int tail) { var chunkStart = $startName.codeUnitAt($startOffset + (0x3ff & lead)); var index = chunkStart + (0x3ff & tail); return $dataName.codeUnitAt(index); } -""" - : """ +"""; + } + var shift = chunkSize.bitLength - 1; + var indexVar = chunkSize < 1024 ? "tail" : "offset"; + return """ +$preferInline int $name(int lead, int tail) { - var offset = ((0x3ff & lead) << 10) | (0x3ff & tail); - var chunkStart = $startName.codeUnitAt($startOffset + (offset >> ${chunkSize.bitLength - 1})); - var index = chunkStart + (offset & ${chunkSize - 1}); + var offset = (((0x3ff & lead) << 10) + (0x3ff & tail)) + ($startOffset << $shift); + var chunkStart = $startName.codeUnitAt(offset >> $shift); + var index = chunkStart + ($indexVar & ${chunkSize - 1}); return $dataName.codeUnitAt(index); } """; +} // ----------------------------------------------------------------------------- bool _validate(Uint8List table, IndirectTable indirectTable, int lowChunkSize, diff --git a/pkgs/characters/tool/src/automaton_builder.dart b/pkgs/characters/tool/src/automaton_builder.dart index 44c526a4..55cc94eb 100644 --- a/pkgs/characters/tool/src/automaton_builder.dart +++ b/pkgs/characters/tool/src/automaton_builder.dart @@ -299,11 +299,13 @@ void writeForwardAutomaton(StringSink buffer, {required bool verbose}) { } const String _moveMethod = """ +$preferInline int move(int state, int inputCategory) => _stateMachine.codeUnitAt((state & $maskState) + inputCategory); """; const String _moveBackMethod = """ +$preferInline int moveBack(int state, int inputCategory) => _backStateMachine.codeUnitAt((state & $maskState) + inputCategory); """; @@ -721,3 +723,8 @@ String _targetStateName(int state, int flags) { if (flags == flagLookahead) return backStateShortName(state); return stateShortName(state); } + +const preferInline = """ +@pragma('dart2js:prefer-inline') +@pragma('vm:prefer-inline') +@pragma('wasm:prefer-inline')""";