|
16 | 16 | */ |
17 | 17 | package de.inetsoftware.jwebassembly.module; |
18 | 18 |
|
| 19 | +import java.util.ArrayDeque; |
19 | 20 | import java.util.ArrayList; |
20 | 21 | import java.util.Arrays; |
21 | 22 | import java.util.Collections; |
22 | 23 | import java.util.HashMap; |
23 | 24 | import java.util.List; |
24 | 25 |
|
| 26 | +import javax.annotation.Nonnull; |
| 27 | + |
25 | 28 | import de.inetsoftware.classparser.CodeInputStream; |
26 | 29 | import de.inetsoftware.jwebassembly.WasmException; |
27 | 30 |
|
@@ -252,11 +255,12 @@ private void calculateIf( BranchNode parent, IfParsedBlock startBlock, List<Pars |
252 | 255 | ParsedBlock parsedBlock = parsedOperations.get( i ); |
253 | 256 | if( parsedBlock.startPosition == gotoPos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition) { |
254 | 257 | parsedOperations.remove( i ); |
255 | | - branch = new BranchNode( startPos, startBlock.endPosition, WasmBlockOperator.IF, null, ValueType.empty ); |
| 258 | + branch = new BranchNode( startPos, startBlock.endPosition, WasmBlockOperator.IF, null ); |
256 | 259 | parent.add( branch ); |
257 | 260 | if( i > 0 ) { |
258 | 261 | calculate( branch, parsedOperations.subList( 0, i ) ); |
259 | 262 | } |
| 263 | + branch.data = calculateBlockType( startPos, branch.endPos ); |
260 | 264 | endPos = parsedBlock.endPosition; |
261 | 265 |
|
262 | 266 | int breakDeep = calculateBreakDeep( parent, endPos ); |
@@ -313,6 +317,39 @@ private int calculateBreakDeep( BranchNode parent, int endPos ) { |
313 | 317 | return deep; |
314 | 318 | } |
315 | 319 |
|
| 320 | + /** |
| 321 | + * Calculate the block type. The value type that is on the stack after the block. |
| 322 | + * |
| 323 | + * @param startPos |
| 324 | + * the start position of the block |
| 325 | + * @param endPos |
| 326 | + * the end position of the block |
| 327 | + * @return the value type |
| 328 | + */ |
| 329 | + @Nonnull |
| 330 | + private ValueType calculateBlockType( int startPos, int endPos ) { |
| 331 | + ArrayDeque<ValueType> stack = new ArrayDeque<>(); |
| 332 | + stack.push( ValueType.empty ); |
| 333 | + for( WasmInstruction instr : instructions ) { |
| 334 | + int codePos = instr.getCodePosition(); |
| 335 | + if( codePos < startPos ) { |
| 336 | + continue; |
| 337 | + } |
| 338 | + if( codePos >= endPos ) { |
| 339 | + break; |
| 340 | + } |
| 341 | + int popCount = instr.getPopCount(); |
| 342 | + for( int p = 0; p < popCount; p++ ) { |
| 343 | + stack.pop(); |
| 344 | + } |
| 345 | + ValueType pushValue = instr.getPushValueType(); |
| 346 | + if( pushValue != null ) { |
| 347 | + stack.push( pushValue ); |
| 348 | + } |
| 349 | + } |
| 350 | + return stack.pop(); |
| 351 | + } |
| 352 | + |
316 | 353 | /** |
317 | 354 | * Calculate the blocks of a switch. |
318 | 355 | * |
|
0 commit comments