@futpib/parser 1.0.3 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/.claude/settings.local.json +24 -0
  2. package/.github/workflows/main.yml +1 -0
  3. package/build/androidPackageParser.js +30 -32
  4. package/build/arbitraryDalvikBytecode.d.ts +3 -3
  5. package/build/arbitraryDalvikBytecode.js +33 -27
  6. package/build/arbitraryDalvikExecutable.js +55 -17
  7. package/build/arbitraryJava.d.ts +31 -0
  8. package/build/arbitraryJava.js +532 -0
  9. package/build/arbitraryJavaScript.d.ts +3 -0
  10. package/build/arbitraryJavaScript.js +263 -0
  11. package/build/arbitraryJavascript.d.ts +3 -0
  12. package/build/arbitraryJavascript.js +263 -0
  13. package/build/arbitraryZig.d.ts +3 -0
  14. package/build/arbitraryZig.js +240 -0
  15. package/build/arbitraryZipStream.d.ts +1 -1
  16. package/build/arrayParser.js +72 -13
  17. package/build/backsmali.d.ts +4 -3
  18. package/build/backsmali.js +26 -6
  19. package/build/bash.d.ts +89 -0
  20. package/build/bash.js +1 -0
  21. package/build/bashParser.d.ts +6 -0
  22. package/build/bashParser.js +335 -0
  23. package/build/bashParser.test.d.ts +1 -0
  24. package/build/bashParser.test.js +343 -0
  25. package/build/bashParserEdgeCases.test.d.ts +1 -0
  26. package/build/bashParserEdgeCases.test.js +117 -0
  27. package/build/dalvikBytecodeParser/addressConversion.d.ts +110 -0
  28. package/build/dalvikBytecodeParser/addressConversion.js +334 -0
  29. package/build/dalvikBytecodeParser/formatParsers.d.ts +7 -6
  30. package/build/dalvikBytecodeParser/formatParsers.js +13 -14
  31. package/build/dalvikBytecodeParser.d.ts +60 -31
  32. package/build/dalvikBytecodeParser.js +92 -35
  33. package/build/dalvikBytecodeParser.test-d.d.ts +1 -0
  34. package/build/dalvikBytecodeParser.test-d.js +268 -0
  35. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +9 -8
  36. package/build/dalvikBytecodeUnparser/formatUnparsers.js +13 -12
  37. package/build/dalvikBytecodeUnparser.d.ts +2 -2
  38. package/build/dalvikBytecodeUnparser.js +23 -23
  39. package/build/dalvikBytecodeUnparser.test.js +7 -7
  40. package/build/dalvikExecutable.d.ts +3 -3
  41. package/build/dalvikExecutable.test-d.d.ts +1 -0
  42. package/build/dalvikExecutable.test-d.js +59 -0
  43. package/build/dalvikExecutableParser/typedNumbers.d.ts +18 -0
  44. package/build/dalvikExecutableParser/typedNumbers.js +3 -0
  45. package/build/dalvikExecutableParser.d.ts +2 -1
  46. package/build/dalvikExecutableParser.js +96 -77
  47. package/build/dalvikExecutableParser.test.js +24 -3
  48. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +3 -0
  49. package/build/dalvikExecutableUnparser/poolScanners.d.ts +2 -2
  50. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +3 -3
  51. package/build/dalvikExecutableUnparser/sectionUnparsers.js +26 -11
  52. package/build/dalvikExecutableUnparser.d.ts +2 -2
  53. package/build/dalvikExecutableUnparser.test.js +2 -1
  54. package/build/disjunctionParser.d.ts +5 -3
  55. package/build/disjunctionParser.js +79 -17
  56. package/build/disjunctionParser.test-d.d.ts +1 -0
  57. package/build/disjunctionParser.test-d.js +72 -0
  58. package/build/elementSwitchParser.d.ts +4 -0
  59. package/build/{exactElementSwitchParser.js → elementSwitchParser.js} +3 -4
  60. package/build/elementSwitchParser.test-d.d.ts +1 -0
  61. package/build/elementSwitchParser.test-d.js +44 -0
  62. package/build/exactSequenceParser.d.ts +4 -2
  63. package/build/exactSequenceParser.test-d.d.ts +1 -0
  64. package/build/exactSequenceParser.test-d.js +36 -0
  65. package/build/fetchCid.js +2 -66
  66. package/build/index.d.ts +25 -2
  67. package/build/index.js +23 -1
  68. package/build/index.test.js +16 -1
  69. package/build/inputReader.d.ts +10 -0
  70. package/build/inputReader.js +36 -0
  71. package/build/java.d.ts +502 -0
  72. package/build/java.js +2 -0
  73. package/build/javaKeyStoreParser.js +14 -17
  74. package/build/javaParser.d.ts +51 -0
  75. package/build/javaParser.js +1538 -0
  76. package/build/javaParser.test.d.ts +1 -0
  77. package/build/javaParser.test.js +1287 -0
  78. package/build/javaScript.d.ts +35 -0
  79. package/build/javaScript.js +1 -0
  80. package/build/javaScriptParser.d.ts +9 -0
  81. package/build/javaScriptParser.js +34 -0
  82. package/build/javaScriptUnparser.d.ts +3 -0
  83. package/build/javaScriptUnparser.js +4 -0
  84. package/build/javaScriptUnparser.test.d.ts +1 -0
  85. package/build/javaScriptUnparser.test.js +24 -0
  86. package/build/javaUnparser.d.ts +2 -0
  87. package/build/javaUnparser.js +519 -0
  88. package/build/javaUnparser.test.d.ts +1 -0
  89. package/build/javaUnparser.test.js +24 -0
  90. package/build/javascript.d.ts +35 -0
  91. package/build/javascript.js +1 -0
  92. package/build/javascriptParser.d.ts +9 -0
  93. package/build/javascriptParser.js +34 -0
  94. package/build/javascriptUnparser.d.ts +3 -0
  95. package/build/javascriptUnparser.js +4 -0
  96. package/build/javascriptUnparser.test.d.ts +1 -0
  97. package/build/javascriptUnparser.test.js +24 -0
  98. package/build/jsonParser.js +2 -12
  99. package/build/lazyMessageError.d.ts +3 -0
  100. package/build/lookaheadParser.js +60 -3
  101. package/build/negativeLookaheadParser.js +70 -11
  102. package/build/nonEmptyArrayParser.js +72 -13
  103. package/build/objectParser.d.ts +12 -0
  104. package/build/objectParser.js +31 -0
  105. package/build/objectParser.test-d.d.ts +1 -0
  106. package/build/objectParser.test-d.js +112 -0
  107. package/build/objectParser.test.d.ts +1 -0
  108. package/build/objectParser.test.js +55 -0
  109. package/build/optionalParser.js +69 -10
  110. package/build/parser.d.ts +4 -0
  111. package/build/parser.js +3 -1
  112. package/build/parser.test.js +114 -1
  113. package/build/parserConsumedSequenceParser.js +66 -7
  114. package/build/parserContext.d.ts +6 -0
  115. package/build/parserContext.js +20 -11
  116. package/build/parserError.d.ts +119 -27
  117. package/build/parserError.js +16 -8
  118. package/build/regexpParser.d.ts +2 -0
  119. package/build/regexpParser.js +101 -0
  120. package/build/regexpParser.test.d.ts +1 -0
  121. package/build/regexpParser.test.js +114 -0
  122. package/build/regularExpression.d.ts +63 -0
  123. package/build/regularExpression.js +1 -0
  124. package/build/regularExpressionParser.d.ts +3 -0
  125. package/build/regularExpressionParser.js +600 -0
  126. package/build/regularExpressionParser.test.d.ts +1 -0
  127. package/build/regularExpressionParser.test.js +89 -0
  128. package/build/separatedArrayParser.js +73 -14
  129. package/build/separatedNonEmptyArrayParser.js +73 -14
  130. package/build/sliceBoundedParser.js +62 -5
  131. package/build/smaliParser.d.ts +7 -7
  132. package/build/smaliParser.js +185 -268
  133. package/build/smaliParser.test.js +58 -0
  134. package/build/stringEscapes.d.ts +5 -0
  135. package/build/stringEscapes.js +244 -0
  136. package/build/symbolicExpression.d.ts +29 -0
  137. package/build/symbolicExpression.js +1 -0
  138. package/build/symbolicExpressionParser.d.ts +4 -0
  139. package/build/symbolicExpressionParser.js +123 -0
  140. package/build/symbolicExpressionParser.test.d.ts +1 -0
  141. package/build/symbolicExpressionParser.test.js +289 -0
  142. package/build/terminatedArrayParser.js +113 -38
  143. package/build/terminatedArrayParser.test.js +4 -2
  144. package/build/tupleParser.d.ts +7 -15
  145. package/build/tupleParser.js +1 -0
  146. package/build/unionParser.d.ts +5 -3
  147. package/build/unionParser.js +7 -2
  148. package/build/unionParser.test-d.d.ts +1 -0
  149. package/build/unionParser.test-d.js +72 -0
  150. package/build/unionParser.test.js +10 -11
  151. package/build/zig.d.ts +280 -0
  152. package/build/zig.js +2 -0
  153. package/build/zigParser.d.ts +3 -0
  154. package/build/zigParser.js +1119 -0
  155. package/build/zigParser.test.d.ts +1 -0
  156. package/build/zigParser.test.js +1590 -0
  157. package/build/zigUnparser.d.ts +2 -0
  158. package/build/zigUnparser.js +460 -0
  159. package/build/zigUnparser.test.d.ts +1 -0
  160. package/build/zigUnparser.test.js +24 -0
  161. package/build/zipParser.js +19 -32
  162. package/build/zipUnparser.js +19 -7
  163. package/build/zipUnparser.test.js +1 -1
  164. package/node_modules-@types/s-expression/index.d.ts +5 -0
  165. package/package.json +25 -6
  166. package/src/androidPackageParser.ts +33 -60
  167. package/src/arbitraryDalvikBytecode.ts +39 -31
  168. package/src/arbitraryDalvikExecutable.ts +65 -20
  169. package/src/arbitraryJava.ts +804 -0
  170. package/src/arbitraryJavaScript.ts +410 -0
  171. package/src/arbitraryZig.ts +380 -0
  172. package/src/arrayParser.ts +1 -3
  173. package/src/backsmali.ts +35 -4
  174. package/src/bash.ts +127 -0
  175. package/src/bashParser.test.ts +590 -0
  176. package/src/bashParser.ts +498 -0
  177. package/src/dalvikBytecodeParser/addressConversion.ts +496 -0
  178. package/src/dalvikBytecodeParser/formatParsers.ts +19 -29
  179. package/src/dalvikBytecodeParser.test-d.ts +310 -0
  180. package/src/dalvikBytecodeParser.ts +194 -69
  181. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +27 -26
  182. package/src/dalvikBytecodeUnparser.test.ts +7 -7
  183. package/src/dalvikBytecodeUnparser.ts +31 -30
  184. package/src/dalvikExecutable.test-d.ts +132 -0
  185. package/src/dalvikExecutable.ts +3 -3
  186. package/src/dalvikExecutableParser/typedNumbers.ts +11 -0
  187. package/src/dalvikExecutableParser.test.ts +37 -3
  188. package/src/dalvikExecutableParser.test.ts.md +163 -2
  189. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  190. package/src/dalvikExecutableParser.ts +121 -139
  191. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +4 -0
  192. package/src/dalvikExecutableUnparser/poolScanners.ts +6 -6
  193. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +38 -14
  194. package/src/dalvikExecutableUnparser.test.ts +3 -2
  195. package/src/dalvikExecutableUnparser.ts +4 -4
  196. package/src/disjunctionParser.test-d.ts +105 -0
  197. package/src/disjunctionParser.ts +18 -15
  198. package/src/elementSwitchParser.test-d.ts +74 -0
  199. package/src/elementSwitchParser.ts +51 -0
  200. package/src/exactSequenceParser.test-d.ts +43 -0
  201. package/src/exactSequenceParser.ts +13 -8
  202. package/src/fetchCid.ts +2 -76
  203. package/src/index.test.ts +22 -1
  204. package/src/index.ts +119 -2
  205. package/src/inputReader.ts +53 -0
  206. package/src/java.ts +708 -0
  207. package/src/javaKeyStoreParser.ts +18 -32
  208. package/src/javaParser.test.ts +1592 -0
  209. package/src/javaParser.ts +2640 -0
  210. package/src/javaScript.ts +36 -0
  211. package/src/javaScriptParser.ts +57 -0
  212. package/src/javaScriptUnparser.test.ts +37 -0
  213. package/src/javaScriptUnparser.ts +7 -0
  214. package/src/javaUnparser.test.ts +37 -0
  215. package/src/javaUnparser.ts +640 -0
  216. package/src/jsonParser.ts +6 -27
  217. package/src/lookaheadParser.ts +2 -6
  218. package/src/negativeLookaheadParser.ts +1 -3
  219. package/src/nonEmptyArrayParser.ts +1 -3
  220. package/src/objectParser.test-d.ts +152 -0
  221. package/src/objectParser.test.ts +71 -0
  222. package/src/objectParser.ts +69 -0
  223. package/src/optionalParser.ts +1 -3
  224. package/src/parser.test.ts +151 -4
  225. package/src/parser.ts +11 -1
  226. package/src/parserConsumedSequenceParser.ts +2 -4
  227. package/src/parserContext.ts +26 -11
  228. package/src/parserError.ts +17 -3
  229. package/src/regexpParser.test.ts +264 -0
  230. package/src/regexpParser.ts +126 -0
  231. package/src/regularExpression.ts +24 -0
  232. package/src/regularExpressionParser.test.ts +102 -0
  233. package/src/regularExpressionParser.ts +920 -0
  234. package/src/separatedArrayParser.ts +1 -3
  235. package/src/separatedNonEmptyArrayParser.ts +1 -3
  236. package/src/sliceBoundedParser.test.ts +2 -2
  237. package/src/sliceBoundedParser.ts +15 -19
  238. package/src/smaliParser.test.ts +64 -0
  239. package/src/smaliParser.test.ts.md +12 -12
  240. package/src/smaliParser.test.ts.snap +0 -0
  241. package/src/smaliParser.ts +246 -534
  242. package/src/stringEscapes.ts +253 -0
  243. package/src/symbolicExpression.ts +17 -0
  244. package/src/symbolicExpressionParser.test.ts +466 -0
  245. package/src/symbolicExpressionParser.ts +190 -0
  246. package/src/terminatedArrayParser.test.ts +9 -6
  247. package/src/terminatedArrayParser.ts +25 -29
  248. package/src/tupleParser.ts +21 -18
  249. package/src/unionParser.test-d.ts +105 -0
  250. package/src/unionParser.test.ts +18 -17
  251. package/src/unionParser.ts +28 -16
  252. package/src/zig.ts +411 -0
  253. package/src/zigParser.test.ts +1693 -0
  254. package/src/zigParser.ts +1745 -0
  255. package/src/zigUnparser.test.ts +37 -0
  256. package/src/zigUnparser.ts +615 -0
  257. package/src/zipParser.ts +20 -56
  258. package/src/zipUnparser.test.ts +1 -1
  259. package/src/zipUnparser.ts +22 -7
  260. package/tsconfig.json +2 -2
  261. package/build/exactElementSwitchParser.d.ts +0 -3
  262. package/src/exactElementSwitchParser.ts +0 -41
@@ -1,7 +1,9 @@
1
1
  import invariant from 'invariant';
2
- import { dalvikBytecodeOperationCompanion } from './dalvikBytecodeParser.js';
2
+ import { rawDalvikBytecodeOperationCompanion } from './dalvikBytecodeParser.js';
3
+ import { getOperationSizeInCodeUnits } from './dalvikBytecodeParser/addressConversion.js';
3
4
  import { dalvikExecutableAccessFlagsDefault, dalvikExecutableFieldEquals, dalvikExecutableMethodEquals, isDalvikExecutableField, isDalvikExecutableMethod, } from './dalvikExecutable.js';
4
5
  import { createExactSequenceParser } from './exactSequenceParser.js';
6
+ import { createObjectParser } from './objectParser.js';
5
7
  import { cloneParser, setParserName } from './parser.js';
6
8
  import { promiseCompose } from './promiseCompose.js';
7
9
  import { createTupleParser } from './tupleParser.js';
@@ -14,37 +16,17 @@ import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
14
16
  import { createSeparatedArrayParser } from './separatedArrayParser.js';
15
17
  import { smaliMemberNameParser, smaliTypeDescriptorParser } from './dalvikExecutableParser/stringSyntaxParser.js';
16
18
  import { createDisjunctionParser } from './disjunctionParser.js';
17
- import { formatSizes } from './dalvikBytecodeParser/formatSizes.js';
18
- import { operationFormats } from './dalvikBytecodeParser/operationFormats.js';
19
19
  import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
20
20
  import { parserCreatorCompose } from './parserCreatorCompose.js';
21
21
  import { createElementParser } from './elementParser.js';
22
22
  import { createParserAccessorParser } from './parserAccessorParser.js';
23
+ import { createRegExpParser } from './regexpParser.js';
23
24
  function shortyFromLongy(longy) {
24
25
  if (longy.startsWith('[')) {
25
26
  return 'L';
26
27
  }
27
28
  return longy.slice(0, 1);
28
29
  }
29
- function getOperationFormatSize(operation) {
30
- if (operation.operation === 'packed-switch-payload') {
31
- return (operation.branchOffsetIndices.length * 2) + 4;
32
- }
33
- if (operation.operation === 'sparse-switch-payload') {
34
- return (operation.branchOffsetIndices.length * 4) + 2;
35
- }
36
- if (operation.operation === 'fill-array-data-payload') {
37
- const dataSize = operation.data.length; // in bytes
38
- const paddingSize = dataSize % 2; // 1 if odd, 0 if even
39
- const totalBytes = 8 + dataSize + paddingSize; // header (8 bytes) + data + padding
40
- return totalBytes / 2; // Convert to code units (1 code unit = 2 bytes)
41
- }
42
- const operationFormat = operationFormats[operation.operation];
43
- invariant(operationFormat, 'Unknown operation format for "%s" (operation: %o)', operation.operation, operation);
44
- const operationSize = formatSizes[operationFormat];
45
- invariant(operationSize, 'Unknown operation size for format %s of operation %s', operationFormat, operation.operation);
46
- return operationSize;
47
- }
48
30
  // Helper function to convert raw annotation element values to tagged encoded values
49
31
  function convertToTaggedEncodedValue(wrappedValue) {
50
32
  const { kind, value } = wrappedValue;
@@ -141,22 +123,8 @@ const smaliSingleIndentationParser = createExactSequenceParser(' ');
141
123
  const smaliIndentationParser = promiseCompose(createArrayParser(smaliSingleIndentationParser), _indentation => undefined);
142
124
  export const smaliCommentParser = promiseCompose(createTupleParser([
143
125
  createExactSequenceParser('#'),
144
- (async (parserContext) => {
145
- const characters = [];
146
- while (true) {
147
- const character = await parserContext.peek(0);
148
- parserContext.invariant(character !== undefined, 'Unexpected end of input');
149
- invariant(character !== undefined, 'Unexpected end of input');
150
- if (character !== '\n') {
151
- characters.push(character);
152
- parserContext.skip(1);
153
- continue;
154
- }
155
- parserContext.skip(1);
156
- break;
157
- }
158
- return characters.join('');
159
- }),
126
+ promiseCompose(createRegExpParser(/[^\n]*/), match => match[0]),
127
+ createExactSequenceParser('\n'),
160
128
  ]), ([_hash, comment,]) => comment);
161
129
  const smaliIndentedCommentParser = promiseCompose(createTupleParser([
162
130
  createNonEmptyArrayParser(smaliSingleIndentationParser),
@@ -174,46 +142,18 @@ const smaliLineEndPraser = promiseCompose(createTupleParser([
174
142
  smaliCommentParser,
175
143
  ]),
176
144
  ]), ([_optionalWhitespace, newlineOrComment,]) => newlineOrComment);
177
- const smaliIdentifierParser = async (parserContext) => {
178
- const characters = [];
179
- while (true) {
180
- const character = await parserContext.peek(0);
181
- parserContext.invariant(character !== undefined, 'Unexpected end of input');
182
- invariant(character !== undefined, 'Unexpected end of input');
183
- if (character === '_'
184
- || (character >= 'a' && character <= 'z')
185
- || (character >= 'A' && character <= 'Z')
186
- || (character >= '0' && character <= '9')) {
187
- parserContext.skip(1);
188
- characters.push(character);
189
- continue;
190
- }
191
- parserContext.invariant(characters.length > 0, 'Expected at least one character');
192
- break;
193
- }
194
- return characters.join('');
195
- };
145
+ const smaliIdentifierParser = promiseCompose(createRegExpParser(/[a-zA-Z0-9_]+/), match => match[0]);
196
146
  setParserName(smaliIdentifierParser, 'smaliIdentifierParser');
197
- const elementParser = createElementParser();
198
- const smaliHexNumberParser = promiseCompose(createTupleParser([
199
- createOptionalParser(createExactSequenceParser('-')),
200
- createExactSequenceParser('0x'),
201
- createArrayParser(parserCreatorCompose(() => elementParser, character => async (parserContext) => {
202
- parserContext.invariant(((character >= '0' && character <= '9')
203
- || (character >= 'a' && character <= 'f')
204
- || (character >= 'A' && character <= 'F')), 'Expected "0" to "9", "a" to "f", "A" to "F", got "%s"', character);
205
- return character;
206
- })()),
207
- createOptionalParser(createExactSequenceParser('L')),
208
- ]), ([optionalMinus, _0x, valueCharacters, optionalL,]) => {
209
- const value = valueCharacters.join('');
147
+ const smaliHexNumberParser = promiseCompose(createRegExpParser(/-?0x([0-9a-fA-F]+)(L)?/), match => {
148
+ const hexDigits = match[1];
149
+ const optionalL = match[2];
210
150
  // If the 'L' suffix is present, use BigInt for long values
211
151
  if (optionalL) {
212
- const sign = optionalMinus ? -1n : 1n;
213
- return sign * BigInt('0x' + value);
152
+ const sign = match[0].startsWith('-') ? -1n : 1n;
153
+ return sign * BigInt('0x' + hexDigits);
214
154
  }
215
- const sign = optionalMinus ? -1 : 1;
216
- return sign * Number.parseInt(value, 16);
155
+ const sign = match[0].startsWith('-') ? -1 : 1;
156
+ return sign * Number.parseInt(hexDigits, 16);
217
157
  });
218
158
  const smaliNumberParser = createUnionParser([
219
159
  promiseCompose(createTupleParser([
@@ -361,13 +301,11 @@ const smaliClassDeclarationParser = promiseCompose(createTupleParser([
361
301
  class: classPath,
362
302
  }));
363
303
  setParserName(smaliClassDeclarationParser, 'smaliClassDeclarationParser');
364
- const smaliSuperDeclarationParser = promiseCompose(createTupleParser([
365
- createExactSequenceParser('.super '),
366
- smaliTypeDescriptorParser,
367
- smaliLineEndPraser,
368
- ]), ([_super, superclass, _newline,]) => ({
369
- superclass,
370
- }));
304
+ const smaliSuperDeclarationParser = createObjectParser({
305
+ _super: createExactSequenceParser('.super '),
306
+ superclass: smaliTypeDescriptorParser,
307
+ _newline: smaliLineEndPraser,
308
+ });
371
309
  setParserName(smaliSuperDeclarationParser, 'smaliSuperDeclarationParser');
372
310
  const smaliInterfaceDeclarationParser = promiseCompose(createTupleParser([
373
311
  createExactSequenceParser('.implements '),
@@ -375,25 +313,19 @@ const smaliInterfaceDeclarationParser = promiseCompose(createTupleParser([
375
313
  smaliLineEndPraser,
376
314
  ]), ([_interface, interface_, _newline,]) => interface_);
377
315
  setParserName(smaliInterfaceDeclarationParser, 'smaliInterfaceDeclarationParser');
378
- const smaliSourceDeclarationParser = promiseCompose(createTupleParser([
379
- createExactSequenceParser('.source '),
380
- smaliQuotedStringParser,
381
- smaliLineEndPraser,
382
- ]), ([_source, sourceFile, _newline,]) => ({
383
- sourceFile,
384
- }));
385
- const smaliEnumValueParser = promiseCompose(createTupleParser([
386
- createExactSequenceParser('.enum '),
387
- smaliTypeDescriptorParser,
388
- createExactSequenceParser('->'),
389
- smaliMemberNameParser,
390
- createExactSequenceParser(':'),
391
- smaliTypeDescriptorParser,
392
- ]), ([_enum, classType, _arrow, fieldName, _colon, fieldType,]) => ({
393
- class: classType,
394
- type: fieldType,
395
- name: fieldName,
396
- }));
316
+ const smaliSourceDeclarationParser = createObjectParser({
317
+ _source: createExactSequenceParser('.source '),
318
+ sourceFile: smaliQuotedStringParser,
319
+ _newline: smaliLineEndPraser,
320
+ });
321
+ const smaliEnumValueParser = createObjectParser({
322
+ _enum: createExactSequenceParser('.enum '),
323
+ class: smaliTypeDescriptorParser,
324
+ _arrow: createExactSequenceParser('->'),
325
+ name: smaliMemberNameParser,
326
+ _colon: createExactSequenceParser(':'),
327
+ type: smaliTypeDescriptorParser,
328
+ });
397
329
  setParserName(smaliEnumValueParser, 'smaliEnumValueParser');
398
330
  const smaliMethodPrototypeParser = promiseCompose(createTupleParser([
399
331
  createExactSequenceParser('('),
@@ -411,16 +343,12 @@ const smaliMethodPrototypeParser = promiseCompose(createTupleParser([
411
343
  }).join(''),
412
344
  }));
413
345
  setParserName(smaliMethodPrototypeParser, 'smaliMethodPrototypeParser');
414
- const smaliParametersMethodParser = promiseCompose(createTupleParser([
415
- smaliTypeDescriptorParser,
416
- createExactSequenceParser('->'),
417
- smaliMemberNameParser,
418
- smaliMethodPrototypeParser,
419
- ]), ([classPath, _separator, methodName, prototype,]) => ({
420
- class: classPath,
421
- prototype,
422
- name: methodName,
423
- }));
346
+ const smaliParametersMethodParser = createObjectParser({
347
+ class: smaliTypeDescriptorParser,
348
+ _separator: createExactSequenceParser('->'),
349
+ name: smaliMemberNameParser,
350
+ prototype: smaliMethodPrototypeParser,
351
+ });
424
352
  setParserName(smaliParametersMethodParser, 'smaliParametersMethodParser');
425
353
  // Forward declaration to handle circular reference
426
354
  let smaliSubannotationParser;
@@ -429,16 +357,46 @@ const smaliAnnotationElementParser = promiseCompose(createTupleParser([
429
357
  smaliIdentifierParser,
430
358
  createExactSequenceParser(' = '),
431
359
  createDisjunctionParser([
432
- promiseCompose(createParserAccessorParser(() => smaliSubannotationParser), value => ({ kind: 'raw', value })),
433
- promiseCompose(smaliEnumValueParser, value => ({ kind: 'enum', value })),
434
- promiseCompose(smaliQuotedStringParser, value => ({ kind: 'string', value })),
435
- promiseCompose(smaliParametersMethodParser, value => ({ kind: 'raw', value })),
436
- promiseCompose(smaliTypeDescriptorParser, value => ({ kind: 'type', value })),
437
- promiseCompose(smaliNumberParser, value => ({ kind: 'raw', value })),
438
- promiseCompose(createExactSequenceParser('true'), () => ({ kind: 'raw', value: true })),
439
- promiseCompose(createExactSequenceParser('false'), () => ({ kind: 'raw', value: false })),
360
+ createObjectParser({
361
+ kind: 'raw',
362
+ value: createParserAccessorParser(() => smaliSubannotationParser),
363
+ }),
364
+ createObjectParser({
365
+ kind: 'enum',
366
+ value: smaliEnumValueParser,
367
+ }),
368
+ createObjectParser({
369
+ kind: 'string',
370
+ value: smaliQuotedStringParser,
371
+ }),
372
+ createObjectParser({
373
+ kind: 'raw',
374
+ value: smaliParametersMethodParser,
375
+ }),
376
+ createObjectParser({
377
+ kind: 'type',
378
+ value: smaliTypeDescriptorParser,
379
+ }),
380
+ createObjectParser({
381
+ kind: 'raw',
382
+ value: smaliNumberParser,
383
+ }),
384
+ createObjectParser({
385
+ kind: 'raw',
386
+ value: true,
387
+ _true: createExactSequenceParser('true'),
388
+ }),
389
+ createObjectParser({
390
+ kind: 'raw',
391
+ value: false,
392
+ _false: createExactSequenceParser('false'),
393
+ }),
440
394
  promiseCompose(createExactSequenceParser('null'), () => ({ kind: 'raw', value: null })),
441
- promiseCompose(createExactSequenceParser('{}'), () => ({ kind: 'raw', value: [] })),
395
+ createObjectParser({
396
+ kind: 'raw',
397
+ value: [],
398
+ _emptyBraces: createExactSequenceParser('{}'),
399
+ }),
442
400
  promiseCompose(createTupleParser([
443
401
  createExactSequenceParser('{\n'),
444
402
  createSeparatedArrayParser(promiseCompose(createTupleParser([
@@ -487,37 +445,30 @@ const smaliAnnotationElementParser = promiseCompose(createTupleParser([
487
445
  }));
488
446
  setParserName(smaliAnnotationElementParser, 'smaliAnnotationElementParser');
489
447
  // Now define the subannotation parser
490
- smaliSubannotationParser = promiseCompose(createTupleParser([
491
- createExactSequenceParser('.subannotation '),
492
- smaliTypeDescriptorParser,
493
- smaliLineEndPraser,
494
- createArrayParser(smaliAnnotationElementParser),
495
- smaliIndentationParser,
496
- createExactSequenceParser('.end subannotation'),
497
- ]), ([_subannotation, type, _newline, elements, _indentation, _endSubannotation,]) => ({
498
- type,
499
- elements,
500
- }));
448
+ smaliSubannotationParser = createObjectParser({
449
+ _subannotation: createExactSequenceParser('.subannotation '),
450
+ type: smaliTypeDescriptorParser,
451
+ _newline: smaliLineEndPraser,
452
+ elements: createArrayParser(smaliAnnotationElementParser),
453
+ _indentation: smaliIndentationParser,
454
+ _endSubannotation: createExactSequenceParser('.end subannotation'),
455
+ });
501
456
  setParserName(smaliSubannotationParser, 'smaliSubannotationParser');
502
- export const smaliAnnotationParser = promiseCompose(createTupleParser([
503
- smaliIndentationParser,
504
- createExactSequenceParser('.annotation '),
505
- createUnionParser([
457
+ export const smaliAnnotationParser = createObjectParser({
458
+ _indentation0: smaliIndentationParser,
459
+ _annotation: createExactSequenceParser('.annotation '),
460
+ visibility: createUnionParser([
506
461
  createExactSequenceParser('build'),
507
462
  createExactSequenceParser('runtime'),
508
463
  createExactSequenceParser('system'),
509
464
  ]),
510
- smaliSingleWhitespaceParser,
511
- smaliTypeDescriptorParser,
512
- smaliLineEndPraser,
513
- createArrayParser(smaliAnnotationElementParser),
514
- smaliIndentationParser,
515
- createExactSequenceParser('.end annotation\n'),
516
- ]), ([_indentation0, _annotation, visibility, _space, type, _newline, elements, _indentation1, _endAnnotation,]) => ({
517
- type,
518
- elements,
519
- visibility,
520
- }));
465
+ _space: smaliSingleWhitespaceParser,
466
+ type: smaliTypeDescriptorParser,
467
+ _newline: smaliLineEndPraser,
468
+ elements: createArrayParser(smaliAnnotationElementParser),
469
+ _indentation1: smaliIndentationParser,
470
+ _endAnnotation: createExactSequenceParser('.end annotation\n'),
471
+ });
521
472
  setParserName(smaliAnnotationParser, 'smaliAnnotationParser');
522
473
  export const smaliFieldParser = promiseCompose(createTupleParser([
523
474
  createExactSequenceParser('.field '),
@@ -640,19 +591,16 @@ function isSmaliRegister(value) {
640
591
  && typeof value.prefix === 'string'
641
592
  && typeof value.index === 'number');
642
593
  }
643
- const smaliParametersRegisterParser = promiseCompose(createUnionParser([
644
- createTupleParser([
645
- createExactSequenceParser('v'),
646
- smaliNumberParser,
647
- ]),
648
- createTupleParser([
649
- createExactSequenceParser('p'),
650
- smaliNumberParser,
651
- ]),
652
- ]), ([prefix, index,]) => ({
653
- prefix,
654
- index,
655
- }));
594
+ const smaliParametersRegisterParser = createUnionParser([
595
+ createObjectParser({
596
+ prefix: createExactSequenceParser('v'),
597
+ index: smaliNumberParser,
598
+ }),
599
+ createObjectParser({
600
+ prefix: createExactSequenceParser('p'),
601
+ index: smaliNumberParser,
602
+ }),
603
+ ]);
656
604
  setParserName(smaliParametersRegisterParser, 'smaliParametersRegisterParser');
657
605
  const smaliCodeLocalParser = promiseCompose(createTupleParser([
658
606
  createExactSequenceParser(' .local '),
@@ -663,12 +611,18 @@ const smaliCodeLocalParser = promiseCompose(createTupleParser([
663
611
  smaliQuotedStringParser,
664
612
  createExactSequenceParser(':'),
665
613
  smaliTypeDescriptorParser,
614
+ createOptionalParser(createTupleParser([
615
+ createExactSequenceParser(','),
616
+ smaliWhitespaceParser,
617
+ smaliQuotedStringParser,
618
+ ])),
666
619
  ])),
667
620
  smaliLineEndPraser,
668
621
  ]), ([_local, register, nameAndType,]) => ({
669
622
  register,
670
623
  name: nameAndType?.[2],
671
624
  type: nameAndType?.[4],
625
+ signature: nameAndType?.[5]?.[2],
672
626
  }));
673
627
  setParserName(smaliCodeLocalParser, 'smaliCodeLocalParser');
674
628
  const smaliCodeEndLocalParser = promiseCompose(createTupleParser([
@@ -732,39 +686,31 @@ const smaliCodeLabelLineParser = promiseCompose(createTupleParser([
732
686
  smaliLineEndPraser,
733
687
  ]), ([_label, label, _newlabel,]) => label);
734
688
  setParserName(smaliCodeLabelLineParser, 'smaliCodeLabelLineParser');
735
- const smaliCatchDirectiveParser = promiseCompose(createTupleParser([
736
- smaliIndentationParser,
737
- createExactSequenceParser('.catch'),
738
- createUnionParser([
689
+ const smaliCatchDirectiveParser = createObjectParser({
690
+ _indentation: smaliIndentationParser,
691
+ _catch: createExactSequenceParser('.catch'),
692
+ type: createUnionParser([
739
693
  promiseCompose(createExactSequenceParser('all'), () => undefined),
740
694
  promiseCompose(createTupleParser([
741
695
  createExactSequenceParser(' '),
742
696
  smaliTypeDescriptorParser,
743
697
  ]), ([_space, type,]) => type),
744
698
  ]),
745
- createExactSequenceParser(' {'),
746
- smaliCodeLabelParser,
747
- createExactSequenceParser(' .. '),
748
- smaliCodeLabelParser,
749
- createExactSequenceParser('} '),
750
- smaliCodeLabelParser,
751
- smaliLineEndPraser,
752
- ]), ([_indentation, _catch, type, _openBrace, startLabel, _dots, endLabel, _closeBrace, handlerLabel, _newline,]) => ({
753
- type,
754
- startLabel,
755
- endLabel,
756
- handlerLabel,
757
- }));
699
+ _openBrace: createExactSequenceParser(' {'),
700
+ startLabel: smaliCodeLabelParser,
701
+ _dots: createExactSequenceParser(' .. '),
702
+ endLabel: smaliCodeLabelParser,
703
+ _closeBrace: createExactSequenceParser('} '),
704
+ handlerLabel: smaliCodeLabelParser,
705
+ _newline: smaliLineEndPraser,
706
+ });
758
707
  setParserName(smaliCatchDirectiveParser, 'smaliCatchDirectiveParser');
759
- const smaliLabeledCatchDirectiveParser = promiseCompose(createTupleParser([
760
- createArrayParser(smaliCodeLineParser),
761
- createOptionalParser(smaliCodeLocalParser),
762
- createArrayParser(smaliCodeLabelLineParser),
763
- smaliCatchDirectiveParser,
764
- ]), ([_lines, _local, labels, catchDirective,]) => ({
765
- labels,
766
- catchDirective,
767
- }));
708
+ const smaliLabeledCatchDirectiveParser = createObjectParser({
709
+ _lines: createArrayParser(smaliCodeLineParser),
710
+ _local: createOptionalParser(smaliCodeLocalParser),
711
+ labels: createArrayParser(smaliCodeLabelLineParser),
712
+ catchDirective: smaliCatchDirectiveParser,
713
+ });
768
714
  setParserName(smaliLabeledCatchDirectiveParser, 'smaliLabeledCatchDirectiveParser');
769
715
  const smaliParametersRegisterRangeParser = promiseCompose(createTupleParser([
770
716
  createExactSequenceParser('{'),
@@ -801,38 +747,15 @@ const smaliParametersRegistersParser = createUnionParser([
801
747
  setParserName(smaliParametersRegistersParser, 'smaliParametersRegistersParser');
802
748
  const smaliParametersStringParser = cloneParser(smaliQuotedStringParser);
803
749
  setParserName(smaliParametersStringParser, 'smaliParametersStringParser');
804
- const smaliParametersIntegerParser = promiseCompose(createTupleParser([
805
- createOptionalParser(createExactSequenceParser('-')),
806
- createExactSequenceParser('0x'),
807
- async (parserContext) => {
808
- const characters = [];
809
- while (true) {
810
- const character = await parserContext.peek(0);
811
- parserContext.invariant(character !== undefined, 'Unexpected end of input');
812
- invariant(character !== undefined, 'Unexpected end of input');
813
- if ((character >= '0' && character <= '9')
814
- || (character >= 'a' && character <= 'f')
815
- || (character >= 'A' && character <= 'F')) {
816
- characters.push(character);
817
- parserContext.skip(1);
818
- continue;
819
- }
820
- break;
821
- }
822
- return characters.join('');
823
- },
824
- createOptionalParser(createUnionParser([
825
- createExactSequenceParser('L'),
826
- createExactSequenceParser('t'),
827
- createExactSequenceParser('s'),
828
- ])),
829
- ]), ([optionalMinus, _0x, value, optionalSuffix,]) => {
750
+ const smaliParametersIntegerParser = promiseCompose(createRegExpParser(/-?0x([0-9a-fA-F]+)([Lts])?/), match => {
751
+ const hexDigits = match[1];
752
+ const optionalSuffix = match[2];
830
753
  if (optionalSuffix === 'L') {
831
- const sign = optionalMinus ? -1n : 1n;
832
- return sign * BigInt('0x' + value);
754
+ const sign = match[0].startsWith('-') ? -1n : 1n;
755
+ return sign * BigInt('0x' + hexDigits);
833
756
  }
834
- const sign = optionalMinus ? -1 : 1;
835
- return sign * Number.parseInt(value, 16);
757
+ const sign = match[0].startsWith('-') ? -1 : 1;
758
+ return sign * Number.parseInt(hexDigits, 16);
836
759
  });
837
760
  setParserName(smaliParametersIntegerParser, 'smaliParametersIntegerParser');
838
761
  const smaliParametersLabelParser = promiseCompose(createTupleParser([
@@ -842,17 +765,13 @@ const smaliParametersLabelParser = promiseCompose(createTupleParser([
842
765
  setParserName(smaliParametersLabelParser, 'smaliParametersLabelParser');
843
766
  const smaliParametersTypeParser = cloneParser(smaliTypeDescriptorParser);
844
767
  setParserName(smaliParametersTypeParser, 'smaliParametersTypeParser');
845
- const smaliParametersFieldParser = promiseCompose(createTupleParser([
846
- smaliTypeDescriptorParser,
847
- createExactSequenceParser('->'),
848
- smaliMemberNameParser,
849
- createExactSequenceParser(':'),
850
- smaliTypeDescriptorParser,
851
- ]), ([classPath, _separator, fieldName, _colon, type,]) => ({
852
- class: classPath,
853
- name: fieldName,
854
- type,
855
- }));
768
+ const smaliParametersFieldParser = createObjectParser({
769
+ class: smaliTypeDescriptorParser,
770
+ _separator: createExactSequenceParser('->'),
771
+ name: smaliMemberNameParser,
772
+ _colon: createExactSequenceParser(':'),
773
+ type: smaliTypeDescriptorParser,
774
+ });
856
775
  setParserName(smaliParametersFieldParser, 'smaliParametersFieldParser');
857
776
  const smaliCodeOperationParametersParser = createArrayParser(promiseCompose(createTupleParser([
858
777
  createUnionParser([
@@ -884,18 +803,15 @@ const smaliCodeOperationNameParser = promiseCompose(createTupleParser([
884
803
  ]), ([slash, name]) => slash + name)),
885
804
  ]), ([name, optionalSlashName,]) => name + (optionalSlashName || ''));
886
805
  setParserName(smaliCodeOperationNameParser, 'smaliCodeOperationNameParser');
887
- const smaliOneLineCodeOperationParser = promiseCompose(createTupleParser([
888
- smaliSingleIndentationParser,
889
- smaliCodeOperationNameParser,
890
- promiseCompose(createOptionalParser(createTupleParser([
806
+ const smaliOneLineCodeOperationParser = createObjectParser({
807
+ _indent: smaliSingleIndentationParser,
808
+ operation: smaliCodeOperationNameParser,
809
+ parameters: promiseCompose(createOptionalParser(createTupleParser([
891
810
  smaliSingleWhitespaceParser,
892
811
  smaliCodeOperationParametersParser,
893
812
  ])), undefinedOrParameters => undefinedOrParameters === undefined ? [] : undefinedOrParameters[1]),
894
- smaliLineEndPraser,
895
- ]), ([_indent, operation, parameters, _newline,]) => ({
896
- operation,
897
- parameters,
898
- }));
813
+ _newline: smaliLineEndPraser,
814
+ });
899
815
  setParserName(smaliOneLineCodeOperationParser, 'smaliOneLineCodeOperationParser');
900
816
  const createMultilineSmaliCodeOperationLabelsBodyParser = operationName => promiseCompose(createTupleParser([
901
817
  createArrayParser(promiseCompose(createTupleParser([
@@ -1223,21 +1139,13 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
1223
1139
  delete operation.branchLabels;
1224
1140
  }
1225
1141
  }
1226
- const branchOffsetByBranchOffsetIndex = new Map();
1227
- let operationOffset = 0;
1228
- for (const [operationIndex, operation] of instructions.entries()) {
1229
- const operationSize = getOperationFormatSize(operation);
1230
- branchOffsetByBranchOffsetIndex.set(operationIndex, operationOffset);
1231
- operationOffset += operationSize;
1232
- }
1142
+ // Convert branchOffsetIndex (relative) to targetInstructionIndex (absolute)
1233
1143
  for (const [operationIndex, operation] of instructions.entries()) {
1234
1144
  if ('branchOffsetIndex' in operation
1235
1145
  && typeof operation.branchOffsetIndex === 'number') {
1236
- const operationOffset = branchOffsetByBranchOffsetIndex.get(operationIndex + operation.branchOffsetIndex);
1237
- invariant(operationOffset !== undefined, 'Expected branch offset for operation index %s, but got undefined', operation.branchOffsetIndex);
1238
- const branchOffset = branchOffsetByBranchOffsetIndex.get(operationIndex);
1239
- invariant(branchOffset !== undefined, 'Expected branch offset for operation index %s, but got undefined', operationIndex);
1240
- operation.branchOffset = operationOffset - branchOffset;
1146
+ // branchOffsetIndex is the relative instruction index from the label
1147
+ // targetInstructionIndex is the absolute instruction index
1148
+ operation.targetInstructionIndex = operationIndex + operation.branchOffsetIndex;
1241
1149
  }
1242
1150
  if ('branchOffsetIndices' in operation
1243
1151
  && typeof operation.branchOffsetIndices === 'object'
@@ -1248,12 +1156,11 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
1248
1156
  invariant(sourceOperations.length === 1, 'Expected exactly one source operation to point to %s', JSON.stringify(operation));
1249
1157
  const [sourceOperation] = sourceOperations;
1250
1158
  const sourceOperationIndex = instructions.indexOf(sourceOperation);
1251
- operation.branchOffsets = operation.branchOffsetIndices.map((branchOffsetIndex) => {
1252
- const operationOffset = branchOffsetByBranchOffsetIndex.get(sourceOperationIndex + branchOffsetIndex);
1253
- invariant(operationOffset !== undefined, 'Expected branch offset for operation index %s, but got undefined', sourceOperationIndex + branchOffsetIndex);
1254
- const branchOffset = branchOffsetByBranchOffsetIndex.get(sourceOperationIndex);
1255
- invariant(branchOffset !== undefined, 'Expected branch offset for operation index %s, but got undefined', sourceOperationIndex);
1256
- return operationOffset - branchOffset;
1159
+ // For payload instructions, branchOffsetIndices contains instruction-relative indices
1160
+ // from the source switch instruction. Convert to absolute instruction indices.
1161
+ operation.targetInstructionIndices = operation.branchOffsetIndices.map((branchOffsetIndex) => {
1162
+ // branchOffsetIndex is relative to the source operation
1163
+ return sourceOperationIndex + branchOffsetIndex;
1257
1164
  });
1258
1165
  }
1259
1166
  }
@@ -1292,6 +1199,7 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
1292
1199
  }
1293
1200
  }
1294
1201
  // Build tries array from catch directives
1202
+ // Now using instruction indices directly instead of code unit offsets
1295
1203
  const triesByRange = new Map();
1296
1204
  for (const catchDirective of catchDirectives) {
1297
1205
  // Find the start and end instruction indices
@@ -1301,44 +1209,53 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
1301
1209
  invariant(startIndex !== undefined, 'Expected to find start label %s', catchDirective.startLabel);
1302
1210
  invariant(endIndex !== undefined, 'Expected to find end label %s', catchDirective.endLabel);
1303
1211
  invariant(handlerIndex !== undefined, 'Expected to find handler label %s', catchDirective.handlerLabel);
1304
- const startAddress = branchOffsetByBranchOffsetIndex.get(startIndex);
1305
- const endAddress = branchOffsetByBranchOffsetIndex.get(endIndex);
1306
- const handlerAddress = branchOffsetByBranchOffsetIndex.get(handlerIndex);
1307
- invariant(startAddress !== undefined, 'Expected start address for index %s', startIndex);
1308
- invariant(endAddress !== undefined, 'Expected end address for index %s', endIndex);
1309
- invariant(handlerAddress !== undefined, 'Expected handler address for index %s', handlerIndex);
1310
- const instructionCount = endAddress - startAddress;
1311
- const rangeKey = `${startAddress}-${instructionCount}`;
1212
+ // Use instruction indices directly
1213
+ const startInstructionIndex = startIndex;
1214
+ const instructionCount = endIndex - startIndex;
1215
+ const handlerInstructionIndex = handlerIndex;
1216
+ const rangeKey = `${startInstructionIndex}-${instructionCount}`;
1312
1217
  let tryEntry = triesByRange.get(rangeKey);
1313
1218
  if (!tryEntry) {
1314
1219
  tryEntry = {
1315
- startAddress,
1220
+ startInstructionIndex,
1316
1221
  instructionCount,
1317
1222
  handlers: [],
1318
- catchAllAddress: undefined,
1223
+ catchAllInstructionIndex: undefined,
1319
1224
  };
1320
1225
  triesByRange.set(rangeKey, tryEntry);
1321
1226
  }
1322
1227
  if (catchDirective.type === undefined) {
1323
1228
  // .catchall
1324
- tryEntry.catchAllAddress = handlerAddress;
1229
+ tryEntry.catchAllInstructionIndex = handlerInstructionIndex;
1325
1230
  }
1326
1231
  else {
1327
1232
  // .catch Type
1328
1233
  tryEntry.handlers.push({
1329
1234
  type: catchDirective.type,
1330
- address: handlerAddress,
1235
+ handlerInstructionIndex,
1331
1236
  });
1332
1237
  }
1333
1238
  }
1334
1239
  const tries = Array.from(triesByRange.values()).map(tryEntry => ({
1335
- startAddress: tryEntry.startAddress,
1240
+ startInstructionIndex: tryEntry.startInstructionIndex,
1336
1241
  instructionCount: tryEntry.instructionCount,
1337
1242
  handler: {
1338
1243
  handlers: tryEntry.handlers,
1339
- catchAllAddress: tryEntry.catchAllAddress,
1244
+ catchAllInstructionIndex: tryEntry.catchAllInstructionIndex,
1340
1245
  },
1341
1246
  }));
1247
+ // Build debug info from debug directives
1248
+ // Debug info still uses code unit offsets (addressDiff), so we need to build the mapping
1249
+ // IMPORTANT: Must be done BEFORE deleting branchOffsetIndices, as getOperationSizeInCodeUnits uses it
1250
+ const codeUnitOffsetByInstructionIndex = new Map();
1251
+ let codeUnitOffset = 0;
1252
+ for (let i = 0; i < instructions.length; i++) {
1253
+ codeUnitOffsetByInstructionIndex.set(i, codeUnitOffset);
1254
+ codeUnitOffset += getOperationSizeInCodeUnits(instructions[i]);
1255
+ }
1256
+ codeUnitOffsetByInstructionIndex.set(instructions.length, codeUnitOffset);
1257
+ // Alias for backward compatibility with debug info code
1258
+ const branchOffsetByBranchOffsetIndex = codeUnitOffsetByInstructionIndex;
1342
1259
  for (const operation of instructions) {
1343
1260
  delete operation.labels;
1344
1261
  delete operation.branchOffsetIndex;
@@ -1603,7 +1520,7 @@ export const smaliMethodParser = promiseCompose(createTupleParser([
1603
1520
  const insSize = (accessFlags.static ? 0 : 1) + shortyGetInsSize(prototype.shorty);
1604
1521
  code.insSize = insSize;
1605
1522
  for (const operation of code.instructions) {
1606
- const smaliRegisters = dalvikBytecodeOperationCompanion.getRegisters(operation); // TODO
1523
+ const smaliRegisters = rawDalvikBytecodeOperationCompanion.getRegisters(operation); // TODO
1607
1524
  if (smaliRegisters.length === 0) {
1608
1525
  continue;
1609
1526
  }
@@ -1623,7 +1540,7 @@ export const smaliMethodParser = promiseCompose(createTupleParser([
1623
1540
  if (!operation.operation.startsWith('invoke-')) {
1624
1541
  continue;
1625
1542
  }
1626
- const registers = dalvikBytecodeOperationCompanion.getRegisters(operation);
1543
+ const registers = rawDalvikBytecodeOperationCompanion.getRegisters(operation);
1627
1544
  outsSize = Math.max(outsSize, registers.length); // TODO?: two words for wide types?
1628
1545
  }
1629
1546
  code.outsSize = outsSize;