mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-03 08:44:44 +00:00
Fixed: #2636 ActionScript 3 - type coercion / convert, local registers type propagation
This commit is contained in:
@@ -2201,6 +2201,11 @@ public class AVM2Code implements Cloneable {
|
||||
vtype = assignment.value.returnType();
|
||||
} else if (assignment.value instanceof LocalRegAVM2Item) {
|
||||
vtype = assignment.value.returnType();
|
||||
} else {
|
||||
vtype = assignment.value.returnType();
|
||||
if (vtype == TypeItem.UNKNOWN) {
|
||||
vtype = TypeItem.UNBOUNDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2435,12 +2440,21 @@ public class AVM2Code implements Cloneable {
|
||||
handleDeclareReg(minreg, subItem, declaredRegisters, declaredSlots, reg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (subItem instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item getLocal = (LocalRegAVM2Item) subItem;
|
||||
if (declaredRegisters[getLocal.regIndex] != null) {
|
||||
getLocal.type = declaredRegisters[getLocal.regIndex].type;
|
||||
}
|
||||
}
|
||||
|
||||
if (subItem instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) subItem;
|
||||
if (declaredRegisters[setLocal.regIndex] != null) {
|
||||
setLocal.type = declaredRegisters[setLocal.regIndex].type;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (subItem instanceof SetPropertyAVM2Item) {
|
||||
SetPropertyAVM2Item sp = (SetPropertyAVM2Item) subItem;
|
||||
if (sp.object instanceof FindPropertyAVM2Item) {
|
||||
@@ -2952,9 +2966,44 @@ public class AVM2Code implements Cloneable {
|
||||
paramNamesList.add(AVM2Item.localRegName(abc.getSwf(), localRegNames, ir, usedDeobfuscations));
|
||||
}
|
||||
injectDeclarations(usedDeobfuscations, 0, paramNamesList, list, 1, d, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), abc, body);
|
||||
|
||||
uniteLocalsDeclarationTypes(d, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private void uniteLocalsDeclarationTypes(DeclarationAVM2Item[] declaredRegs, List<GraphTargetItem> items) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
GraphTargetItem currentItem = items.get(i);
|
||||
List<GraphTargetItem> itemsOnLine = new ArrayList<>();
|
||||
itemsOnLine.add(currentItem);
|
||||
currentItem.visitRecursivelyNoBlock(new AbstractGraphTargetRecursiveVisitor() {
|
||||
@Override
|
||||
public void visit(GraphTargetItem item, Stack<GraphTargetItem> parentStack) {
|
||||
itemsOnLine.add(item);
|
||||
}
|
||||
});
|
||||
|
||||
for (GraphTargetItem item : itemsOnLine) {
|
||||
if (item instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) item;
|
||||
if (declaredRegs[setLocal.regIndex] != null) {
|
||||
setLocal.type = declaredRegs[setLocal.regIndex].type;
|
||||
}
|
||||
}
|
||||
if (item instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item getLocal = (LocalRegAVM2Item) item;
|
||||
if (declaredRegs[getLocal.regIndex] != null) {
|
||||
getLocal.type = declaredRegs[getLocal.regIndex].type;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentItem instanceof Block) {
|
||||
Block block = (Block) currentItem;
|
||||
for (List<GraphTargetItem> sub : block.getSubs()) {
|
||||
uniteLocalsDeclarationTypes(declaredRegs, sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates instruction byte count at given address.
|
||||
|
||||
@@ -43,20 +43,33 @@ import java.util.List;
|
||||
public interface SetTypeIns {
|
||||
|
||||
/**
|
||||
* Handles number to int conversion.
|
||||
* Handles setting value with coerce
|
||||
*
|
||||
* @param value Value to convert
|
||||
* @param type Type to convert to
|
||||
* @return Value
|
||||
*/
|
||||
public static GraphTargetItem handleNumberToInt(GraphTargetItem value, GraphTargetItem type) {
|
||||
if ((value instanceof ConvertAVM2Item) || (value instanceof CoerceAVM2Item)) {
|
||||
if (type != null && (type.equals(TypeItem.INT) || type.equals(TypeItem.UINT))) {
|
||||
if (value.value.returnType().equals(TypeItem.NUMBER)) {
|
||||
return value.value;
|
||||
}
|
||||
public static GraphTargetItem handleSetCoerce(GraphTargetItem value, GraphTargetItem type) {
|
||||
if (type == null) {
|
||||
return value;
|
||||
}
|
||||
if (!(value instanceof ConvertAVM2Item) && !(value instanceof CoerceAVM2Item)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
GraphTargetItem convertType = value.returnType();
|
||||
GraphTargetItem insideConvertType = value.value.returnType();
|
||||
|
||||
if (type.equals(convertType)) {
|
||||
if (insideConvertType.equals(TypeItem.UNBOUNDED) && !type.equals(TypeItem.UNBOUNDED)) {
|
||||
return value.value;
|
||||
}
|
||||
}
|
||||
|
||||
if ((type.equals(TypeItem.INT) || type.equals(TypeItem.UINT)) && insideConvertType.equals(TypeItem.NUMBER)) {
|
||||
return value.value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
|
||||
@@ -35,6 +37,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
|
||||
import com.jpexs.decompiler.graph.model.CompoundableBinaryOp;
|
||||
import com.jpexs.decompiler.graph.model.DuplicateItem;
|
||||
|
||||
@@ -79,30 +79,30 @@ public class CoerceAVM2Item extends AVM2Item {
|
||||
break;
|
||||
case "Boolean":
|
||||
displayCoerce = !valueReturnType.equals(TypeItem.BOOLEAN)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "Number":
|
||||
displayCoerce = !valueReturnType.equals(TypeItem.INT)
|
||||
&& !valueReturnType.equals(TypeItem.NUMBER)
|
||||
&& !valueReturnType.equals(TypeItem.UINT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "float":
|
||||
displayCoerce = !valueReturnType.equals(TypeItem.INT)
|
||||
&& !valueReturnType.equals(new TypeItem("float"))
|
||||
&& !valueReturnType.equals(TypeItem.UINT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "int":
|
||||
displayCoerce = !valueReturnType.equals(TypeItem.INT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "uint":
|
||||
if (valueReturnType.equals(TypeItem.INT) && (value instanceof IntegerValueAVM2Item)) {
|
||||
displayCoerce = (((IntegerValueAVM2Item) value).value < 0);
|
||||
} else {
|
||||
displayCoerce = !valueReturnType.equals(TypeItem.UINT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;// && !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
}
|
||||
break;
|
||||
case "String":
|
||||
|
||||
@@ -67,30 +67,30 @@ public class ConvertAVM2Item extends AVM2Item {
|
||||
switch (type.toString()) {
|
||||
case "Boolean":
|
||||
displayConvert = !valueReturnType.equals(TypeItem.BOOLEAN)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "Number":
|
||||
displayConvert = !valueReturnType.equals(TypeItem.INT)
|
||||
&& !valueReturnType.equals(TypeItem.NUMBER)
|
||||
&& !valueReturnType.equals(TypeItem.UINT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "float":
|
||||
displayConvert = !valueReturnType.equals(TypeItem.INT)
|
||||
&& !valueReturnType.equals(new TypeItem("float"))
|
||||
&& !valueReturnType.equals(TypeItem.UINT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "int":
|
||||
displayConvert = !valueReturnType.equals(TypeItem.INT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
case "uint":
|
||||
if (valueReturnType.equals(TypeItem.INT) && (value instanceof IntegerValueAVM2Item)) {
|
||||
displayConvert = (((IntegerValueAVM2Item) value).value < 0);
|
||||
} else {
|
||||
displayConvert = !valueReturnType.equals(TypeItem.UINT)
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;// && !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
}
|
||||
break;
|
||||
case "String":
|
||||
@@ -98,7 +98,7 @@ public class ConvertAVM2Item extends AVM2Item {
|
||||
//&& !valueReturnType.equals(new TypeItem("XML"))
|
||||
//&& !valueReturnType.equals(new TypeItem("XMLList"))
|
||||
&& !valueReturnType.equals(new TypeItem("null"))
|
||||
&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
;//&& !valueReturnType.equals(TypeItem.UNBOUNDED);
|
||||
break;
|
||||
}
|
||||
if (displayConvert) {
|
||||
|
||||
@@ -120,7 +120,7 @@ public class SetLocalAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assig
|
||||
/*if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) {
|
||||
return value.value.toString(writer, localData);
|
||||
}*/
|
||||
return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData);
|
||||
return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -140,7 +140,7 @@ public class SetPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, As
|
||||
/*if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) {
|
||||
return value.value.toString(writer, localData);
|
||||
}*/
|
||||
return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData);
|
||||
return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,7 +167,7 @@ public class SetPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, As
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return value.returnType();
|
||||
return type;
|
||||
//return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign
|
||||
/*if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) {
|
||||
return value.value.toString(writer, localData);
|
||||
}*/
|
||||
return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData);
|
||||
return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,7 +183,7 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return TypeItem.UNBOUNDED;
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -135,7 +135,7 @@ public class SetSuperAVM2Item extends AVM2Item implements SetTypeAVM2Item {
|
||||
return compoundValue.toString(writer, localData);
|
||||
}
|
||||
writer.append(" = ");
|
||||
return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData);
|
||||
return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -130,7 +130,7 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
type.appendTry(writer, localData);
|
||||
if (showValue) {
|
||||
writer.append(" = ");
|
||||
SetTypeIns.handleNumberToInt(val, type).toString(writer, localData);
|
||||
SetTypeIns.handleSetCoerce(val, type).toString(writer, localData);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
@@ -149,7 +149,7 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
type.appendTry(writer, localData);
|
||||
if (showValue) {
|
||||
writer.append(" = ");
|
||||
SetTypeIns.handleNumberToInt(val, type).toString(writer, localData);
|
||||
SetTypeIns.handleSetCoerce(val, type).toString(writer, localData);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
type.appendTry(writer, localData);
|
||||
if (showValue) {
|
||||
writer.append(" = ");
|
||||
SetTypeIns.handleNumberToInt(val, type).toString(writer, localData);
|
||||
SetTypeIns.handleSetCoerce(val, type).toString(writer, localData);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user