|
|
|
@ -30,57 +30,64 @@ public class CreateNewConstructor { |
|
|
|
|
* (optional DUP) |
|
|
|
|
* PUSH load_ops |
|
|
|
|
* optionally: <= used for "string1 += string2" |
|
|
|
|
* DUP_X2 |
|
|
|
|
* [ n non void + some void expressions ] |
|
|
|
|
* stack_n.<init>(stack_n-1,...,stack_0) |
|
|
|
|
* DUP_X2/1 <= 2 if above DUP is present |
|
|
|
|
* stack_n.<init>((optional: stack_n), resolved expressions) |
|
|
|
|
* |
|
|
|
|
* transform it to |
|
|
|
|
* |
|
|
|
|
* PUSH load_ops |
|
|
|
|
* optionally: |
|
|
|
|
* DUP_X1 <= remove the depth |
|
|
|
|
* [ n non void + some void expressions ] |
|
|
|
|
* (optional PUSH) new <object>(stack_n-1,...,stack_0) |
|
|
|
|
* DUP <= remove the depth |
|
|
|
|
* (optional PUSH) new <object>((optional: stack_n), |
|
|
|
|
* resolved expressions) |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if (!(last.outer instanceof SequentialBlock)) |
|
|
|
|
return false; |
|
|
|
|
if (!(ic.getInstruction() instanceof InvokeOperator)) |
|
|
|
|
if (!(ic.getInstruction().getOperator() instanceof InvokeOperator)) |
|
|
|
|
return false; |
|
|
|
|
InvokeOperator constrCall = (InvokeOperator) ic.getInstruction(); |
|
|
|
|
Expression constrExpr = ic.getInstruction(); |
|
|
|
|
InvokeOperator constrCall = (InvokeOperator) constrExpr.getOperator(); |
|
|
|
|
if (!constrCall.isConstructor()) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
/* The rest should probably succeed */ |
|
|
|
|
int params = constrCall.getOperandCount() - 1; |
|
|
|
|
|
|
|
|
|
SpecialBlock optDupX2 = null; |
|
|
|
|
SequentialBlock sequBlock = (SequentialBlock) last.outer; |
|
|
|
|
while (params > 0) { |
|
|
|
|
if (!(sequBlock.subBlocks[0] instanceof InstructionBlock)) |
|
|
|
|
|
|
|
|
|
if (constrExpr instanceof ComplexExpression) { |
|
|
|
|
Expression[] subs = |
|
|
|
|
((ComplexExpression) constrExpr).getSubExpressions(); |
|
|
|
|
if (!(subs[0] instanceof NopOperator)) |
|
|
|
|
return false; |
|
|
|
|
if (constrExpr.getOperandCount() == 2) { |
|
|
|
|
if (!(subs[1] instanceof NopOperator)) |
|
|
|
|
return false; |
|
|
|
|
if (!(sequBlock.outer instanceof SequentialBlock) |
|
|
|
|
|| !(sequBlock.subBlocks[0] instanceof SpecialBlock)) |
|
|
|
|
return false; |
|
|
|
|
Expression expr |
|
|
|
|
= ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); |
|
|
|
|
if (!expr.isVoid()) |
|
|
|
|
params--; |
|
|
|
|
if (expr.getOperandCount() > 0) { |
|
|
|
|
if (params == 0 |
|
|
|
|
&& sequBlock.outer instanceof SequentialBlock |
|
|
|
|
&& sequBlock.outer.getSubBlocks()[0] |
|
|
|
|
instanceof SpecialBlock) { |
|
|
|
|
/* handle the optional dup */ |
|
|
|
|
sequBlock = (SequentialBlock) sequBlock.outer; |
|
|
|
|
optDupX2 = (SpecialBlock) sequBlock.subBlocks[0]; |
|
|
|
|
sequBlock = (SequentialBlock) sequBlock.outer; |
|
|
|
|
if (optDupX2.type != SpecialBlock.DUP |
|
|
|
|
|| optDupX2.depth != 2) |
|
|
|
|
|| optDupX2.depth == 0) |
|
|
|
|
return false; |
|
|
|
|
params = optDupX2.count; |
|
|
|
|
} else |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (!(sequBlock.outer instanceof SequentialBlock)) |
|
|
|
|
int count = optDupX2.count; |
|
|
|
|
do { |
|
|
|
|
if (!(sequBlock.outer instanceof SequentialBlock) |
|
|
|
|
|| !(sequBlock.subBlocks[0] |
|
|
|
|
instanceof InstructionBlock)) |
|
|
|
|
return false; |
|
|
|
|
Expression expr = |
|
|
|
|
((InstructionBlock) |
|
|
|
|
sequBlock.subBlocks[0]).getInstruction(); |
|
|
|
|
count -= expr.getType().stackSize(); |
|
|
|
|
sequBlock = (SequentialBlock) sequBlock.outer; |
|
|
|
|
} |
|
|
|
|
} while (count > 0); |
|
|
|
|
} else if (constrExpr.getOperandCount() != 1) |
|
|
|
|
return false; |
|
|
|
|
} else if (constrExpr.getOperandCount() != 1) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
while (sequBlock.subBlocks[0] instanceof InstructionBlock |
|
|
|
|
&& ((InstructionBlock)sequBlock.subBlocks[0]) |
|
|
|
@ -97,7 +104,10 @@ public class CreateNewConstructor { |
|
|
|
|
|| dup.count != 1 || dup.depth != 0) |
|
|
|
|
return false; |
|
|
|
|
sequBlock = (SequentialBlock)sequBlock.outer; |
|
|
|
|
} |
|
|
|
|
if (optDupX2 != null && optDupX2.depth != 2) |
|
|
|
|
return false; |
|
|
|
|
} else if (optDupX2 != null && optDupX2.depth != 1) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
if (!(sequBlock.subBlocks[0] instanceof InstructionBlock)) |
|
|
|
|
return false; |
|
|
|
@ -114,9 +124,19 @@ public class CreateNewConstructor { |
|
|
|
|
dup.removeBlock(); |
|
|
|
|
if (optDupX2 != null) |
|
|
|
|
optDupX2.depth = 0; |
|
|
|
|
ic.setInstruction(new ConstructorOperator(constrCall.getClassType(), |
|
|
|
|
constrCall.getMethodType(), |
|
|
|
|
dup == null)); |
|
|
|
|
|
|
|
|
|
Expression newExpr = new ConstructorOperator |
|
|
|
|
(constrCall.getClassType(), constrCall.getMethodType(), |
|
|
|
|
dup == null); |
|
|
|
|
|
|
|
|
|
if (constrExpr instanceof ComplexExpression) { |
|
|
|
|
Expression[] subs = |
|
|
|
|
((ComplexExpression)constrExpr).getSubExpressions(); |
|
|
|
|
for (int i=subs.length - 1; i>=1; i--) |
|
|
|
|
if (!(subs[i] instanceof NopOperator)) |
|
|
|
|
newExpr = newExpr.addOperand(subs[i]); |
|
|
|
|
} |
|
|
|
|
ic.setInstruction(newExpr); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|