Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
c18074f6
Commit
c18074f6
authored
Nov 03, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: insert 'continue' instruction
parent
8a706193
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
149 additions
and
20 deletions
+149
-20
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+1
-1
InsnType.java
...re/src/main/java/jadx/core/dex/instructions/InsnType.java
+13
-6
InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+1
-1
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+2
-1
BlockMakerVisitor.java
...c/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java
+16
-1
IfMakerHelper.java
...in/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
+11
-5
RegionMaker.java
...main/java/jadx/core/dex/visitors/regions/RegionMaker.java
+50
-5
BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+10
-0
TestContinueInLoop.java
...java/jadx/tests/integration/loops/TestContinueInLoop.java
+45
-0
No files found.
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
c18074f6
...
...
@@ -440,7 +440,7 @@ public class InsnGen {
makeTernary
((
TernaryInsn
)
insn
,
code
,
state
);
break
;
case
ARGS
:
case
ONE_ARG
:
addArg
(
code
,
insn
.
getArg
(
0
));
break
;
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/InsnType.java
View file @
c18074f6
package
jadx
.
core
.
dex
.
instructions
;
public
enum
InsnType
{
NOP
,
// replacement for removed instructions
CONST
,
CONST_STR
,
...
...
@@ -48,16 +47,24 @@ public enum InsnType {
INVOKE
,
// additional instructions
// *** Additional instructions ***
// replacement for removed instructions
NOP
,
TERNARY
,
CONSTRUCTOR
,
BREAK
,
CONTINUE
,
STR_CONCAT
,
// strings concatenation
// strings concatenation
STR_CONCAT
,
TERNARY
,
ARGS
,
// just generate arguments
// just generate one argument
ONE_ARG
,
PHI
,
NEW_MULTIDIM_ARRAY
// TODO: now multidimensional arrays created using Array.newInstance function
// TODO: now multidimensional arrays created using Array.newInstance function
NEW_MULTIDIM_ARRAY
}
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
View file @
c18074f6
...
...
@@ -36,7 +36,7 @@ public class InsnNode extends LineAttrNode {
}
public
static
InsnNode
wrapArg
(
InsnArg
arg
)
{
InsnNode
insn
=
new
InsnNode
(
InsnType
.
ARGS
,
1
);
InsnNode
insn
=
new
InsnNode
(
InsnType
.
ONE_ARG
,
1
);
insn
.
addArg
(
arg
);
return
insn
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
c18074f6
...
...
@@ -34,6 +34,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
org.jetbrains.annotations.NotNull
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -519,7 +520,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return
debugInfoOffset
;
}
public
SSAVar
makeNewSVar
(
int
regNum
,
int
[]
versions
,
RegisterArg
arg
)
{
public
SSAVar
makeNewSVar
(
int
regNum
,
int
[]
versions
,
@NotNull
RegisterArg
arg
)
{
SSAVar
var
=
new
SSAVar
(
regNum
,
versions
[
regNum
],
arg
);
versions
[
regNum
]++;
if
(
sVars
.
isEmpty
())
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java
View file @
c18074f6
...
...
@@ -427,9 +427,9 @@ public class BlockMakerVisitor extends AbstractVisitor {
return
true
;
}
}
// insert additional blocks if loop has several exits
if
(
loops
.
size
()
==
1
)
{
LoopInfo
loop
=
loops
.
get
(
0
);
// insert additional blocks for possible 'break' insertion
List
<
Edge
>
edges
=
loop
.
getExitEdges
();
if
(!
edges
.
isEmpty
())
{
boolean
change
=
false
;
...
...
@@ -444,6 +444,21 @@ public class BlockMakerVisitor extends AbstractVisitor {
return
true
;
}
}
// insert additional blocks for possible 'continue' insertion
BlockNode
loopEnd
=
loop
.
getEnd
();
if
(
loopEnd
.
getPredecessors
().
size
()
>
1
)
{
boolean
change
=
false
;
List
<
BlockNode
>
nodes
=
new
ArrayList
<
BlockNode
>(
loopEnd
.
getPredecessors
());
for
(
BlockNode
pred
:
nodes
)
{
if
(!
pred
.
contains
(
AFlag
.
SYNTHETIC
))
{
insertBlockBetween
(
mth
,
pred
,
loopEnd
);
change
=
true
;
}
}
if
(
change
)
{
return
true
;
}
}
}
}
return
splitReturn
(
mth
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
View file @
c18074f6
...
...
@@ -239,13 +239,19 @@ public class IfMakerHelper {
}
static
void
confirmMerge
(
IfInfo
info
)
{
for
(
BlockNode
block
:
info
.
getMergedBlocks
())
{
block
.
add
(
AFlag
.
SKIP
);
if
(
info
.
getMergedBlocks
().
size
()
>
1
)
{
for
(
BlockNode
block
:
info
.
getMergedBlocks
())
{
if
(
block
!=
info
.
getIfBlock
())
{
block
.
add
(
AFlag
.
SKIP
);
}
}
}
for
(
BlockNode
block
:
info
.
getSkipBlocks
())
{
block
.
add
(
AFlag
.
SKIP
);
if
(!
info
.
getSkipBlocks
().
isEmpty
())
{
for
(
BlockNode
block
:
info
.
getSkipBlocks
())
{
block
.
add
(
AFlag
.
SKIP
);
}
info
.
getSkipBlocks
().
clear
();
}
info
.
getSkipBlocks
().
clear
();
}
private
static
IfInfo
getNextIf
(
IfInfo
info
,
BlockNode
block
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
View file @
c18074f6
...
...
@@ -166,7 +166,9 @@ public class RegionMaker {
LoopRegion
loopRegion
=
makeLoopRegion
(
curRegion
,
loop
,
exitBlocks
);
if
(
loopRegion
==
null
)
{
return
makeEndlessLoop
(
curRegion
,
stack
,
loop
,
loopStart
);
BlockNode
exit
=
makeEndlessLoop
(
curRegion
,
stack
,
loop
,
loopStart
);
insertContinueInsns
(
loop
);
return
exit
;
}
curRegion
.
getSubBlocks
().
add
(
loopRegion
);
IRegion
outerRegion
=
stack
.
peekRegion
();
...
...
@@ -233,6 +235,7 @@ public class RegionMaker {
loopRegion
.
setBody
(
body
);
}
stack
.
pop
();
insertContinueInsns
(
loop
);
return
out
;
}
...
...
@@ -359,9 +362,12 @@ public class RegionMaker {
if
(
source
.
contains
(
AType
.
CATCH_BLOCK
)
&&
source
.
getSuccessors
().
size
()
==
2
)
{
BlockNode
other
=
BlockUtils
.
selectOther
(
loopExit
,
source
.
getSuccessors
());
if
(
other
!=
null
&&
other
.
contains
(
AType
.
EXC_HANDLER
))
{
insertBlock
=
source
;
confirm
=
true
;
if
(
other
!=
null
)
{
other
=
BlockUtils
.
skipSyntheticSuccessor
(
other
);
if
(
other
.
contains
(
AType
.
EXC_HANDLER
))
{
insertBlock
=
source
;
confirm
=
true
;
}
}
}
}
...
...
@@ -405,6 +411,45 @@ public class RegionMaker {
return
true
;
}
private
static
void
insertContinueInsns
(
LoopInfo
loop
)
{
BlockNode
loopEnd
=
loop
.
getEnd
();
List
<
BlockNode
>
predecessors
=
loopEnd
.
getPredecessors
();
if
(
predecessors
.
size
()
<=
1
)
{
return
;
}
for
(
BlockNode
pred
:
predecessors
)
{
if
(!
pred
.
contains
(
AFlag
.
SYNTHETIC
)
||
BlockUtils
.
checkLastInsnType
(
pred
,
InsnType
.
CONTINUE
))
{
continue
;
}
List
<
BlockNode
>
nodes
=
pred
.
getPredecessors
();
if
(
nodes
.
isEmpty
())
{
continue
;
}
BlockNode
codePred
=
nodes
.
get
(
0
);
if
(
codePred
.
contains
(
AFlag
.
SKIP
))
{
continue
;
}
if
(!
isDominatedOnBlocks
(
codePred
,
predecessors
))
{
for
(
BlockNode
blockNode
:
predecessors
)
{
if
(
blockNode
!=
pred
&&
BlockUtils
.
isPathExists
(
codePred
,
blockNode
))
{
InsnNode
cont
=
new
InsnNode
(
InsnType
.
CONTINUE
,
0
);
pred
.
getInstructions
().
add
(
cont
);
}
}
}
}
}
private
static
boolean
isDominatedOnBlocks
(
BlockNode
dom
,
List
<
BlockNode
>
blocks
)
{
for
(
BlockNode
node
:
blocks
)
{
if
(!
node
.
isDominator
(
dom
))
{
return
false
;
}
}
return
true
;
}
private
final
Set
<
BlockNode
>
cacheSet
=
new
HashSet
<
BlockNode
>();
private
BlockNode
processMonitorEnter
(
IRegion
curRegion
,
BlockNode
block
,
InsnNode
insn
,
RegionStack
stack
)
{
...
...
@@ -444,7 +489,7 @@ public class RegionMaker {
* Traverse from monitor-enter thru successors and collect blocks contains monitor-exit
*/
private
static
void
traverseMonitorExits
(
SynchronizedRegion
region
,
InsnArg
arg
,
BlockNode
block
,
Set
<
BlockNode
>
exits
,
Set
<
BlockNode
>
visited
)
{
Set
<
BlockNode
>
exits
,
Set
<
BlockNode
>
visited
)
{
visited
.
add
(
block
);
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
insn
.
getType
()
==
InsnType
.
MONITOR_EXIT
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
View file @
c18074f6
...
...
@@ -439,4 +439,14 @@ public class BlockUtils {
}
return
block
==
end
;
}
/**
* Return successor of synthetic block or same block otherwise.
*/
public
static
BlockNode
skipSyntheticSuccessor
(
BlockNode
block
)
{
if
(
block
.
isSynthetic
()
&&
!
block
.
getSuccessors
().
isEmpty
())
{
return
block
.
getSuccessors
().
get
(
0
);
}
return
block
;
}
}
jadx-core/src/test/java/jadx/tests/integration/loops/TestContinueInLoop.java
0 → 100644
View file @
c18074f6
package
jadx
.
tests
.
integration
.
loops
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestContinueInLoop
extends
IntegrationTest
{
public
static
class
TestCls
{
private
int
f
;
private
void
test
(
int
[]
a
,
int
b
)
{
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
int
v
=
a
[
i
];
if
(
v
<
b
)
{
a
[
i
]++;
}
else
if
(
v
>
b
)
{
a
[
i
]--;
}
else
{
continue
;
}
if
(
i
<
b
)
{
break
;
}
}
this
.
f
++;
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"for (int i = 0; i < a.length; i++) {"
));
assertThat
(
code
,
containsOne
(
"if (i < b) {"
));
assertThat
(
code
,
containsOne
(
"continue;"
));
assertThat
(
code
,
containsOne
(
"break;"
));
assertThat
(
code
,
containsOne
(
"this.f++;"
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment