mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-22 18:55:57 +00:00
fix
This commit is contained in:
@@ -16,10 +16,17 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -29,8 +36,161 @@ public class FastActionList {
|
||||
|
||||
private LinkedList<Action> actions;
|
||||
|
||||
public FastActionList(List<Action> actions) {
|
||||
private Map<Action, List<Action>> containerLastActions;
|
||||
|
||||
private Map<Action, Action> jumps;
|
||||
|
||||
public FastActionList(ActionList actions) {
|
||||
this.actions = new LinkedList<>(actions);
|
||||
|
||||
Map<Action, List<Action>> containerLastActions = new HashMap<>();
|
||||
getContainerLastActions(this.actions, actions, containerLastActions);
|
||||
this.containerLastActions = containerLastActions;
|
||||
|
||||
Map<Action, Action> jumps = new HashMap<>();
|
||||
getJumps(actions, jumps);
|
||||
this.jumps = jumps;
|
||||
}
|
||||
|
||||
private void getContainerLastActions(LinkedList<Action> linkedActions, ActionList actions, Map<Action, List<Action>> lastActions) {
|
||||
for (Action a : linkedActions) {
|
||||
if (a instanceof GraphSourceItemContainer) {
|
||||
lastActions.put(a, getContainerLastActions(actions, a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Action> getContainerLastActions(ActionList actions, Action action) {
|
||||
GraphSourceItemContainer container = (GraphSourceItemContainer) action;
|
||||
List<Long> sizes = container.getContainerSizes();
|
||||
long endAddress = action.getAddress() + container.getHeaderSize();
|
||||
List<Action> lasts = new ArrayList<>(sizes.size());
|
||||
for (long size : sizes) {
|
||||
endAddress += size;
|
||||
long lastActionAddress = getNearAddress(actions, endAddress - 1, false);
|
||||
Action lastAction = null;
|
||||
if (lastActionAddress != -1) {
|
||||
lastAction = actions.getByAddress(lastActionAddress);
|
||||
}
|
||||
lasts.add(lastAction);
|
||||
}
|
||||
return lasts;
|
||||
}
|
||||
|
||||
private long getNearAddress(ActionList actions, long address, boolean next) {
|
||||
int min = 0;
|
||||
int max = actions.size() - 1;
|
||||
|
||||
while (max >= min) {
|
||||
int mid = (min + max) / 2;
|
||||
long midValue = actions.get(mid).getAddress();
|
||||
if (midValue == address) {
|
||||
return address;
|
||||
} else if (midValue < address) {
|
||||
min = mid + 1;
|
||||
} else {
|
||||
max = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return next
|
||||
? (min < actions.size() ? actions.get(min).getAddress() : -1)
|
||||
: (max >= 0 ? actions.get(max).getAddress() : -1);
|
||||
}
|
||||
|
||||
private static void getJumps(ActionList actions, Map<Action, Action> jumps) {
|
||||
for (Action a : actions) {
|
||||
long target = -1;
|
||||
if (a instanceof ActionIf) {
|
||||
target = ((ActionIf) a).getTargetAddress();
|
||||
} else if (a instanceof ActionJump) {
|
||||
target = ((ActionJump) a).getTargetAddress();
|
||||
} else if (a instanceof ActionStore) {
|
||||
ActionStore aStore = (ActionStore) a;
|
||||
int storeSize = aStore.getStoreSize();
|
||||
// skip storeSize + 1 actions (+1 is the current action)
|
||||
Action targetAction = a;
|
||||
for (int i = 0; i <= storeSize; i++) {
|
||||
long address = targetAction.getAddress() + targetAction.getTotalActionLength();
|
||||
targetAction = actions.getByAddress(address);
|
||||
if (targetAction == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
jumps.put(a, targetAction);
|
||||
}
|
||||
if (target >= 0) {
|
||||
Action targetAction = actions.getByAddress(target);
|
||||
jumps.put(a, targetAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateJumps(Map<Action, Action> jumps) {
|
||||
if (actions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long endAddress = actions.getLast().getAddress();
|
||||
for (Action a : actions) {
|
||||
if (a instanceof ActionIf) {
|
||||
ActionIf aIf = (ActionIf) a;
|
||||
Action target = jumps.get(a);
|
||||
long offset;
|
||||
if (target != null) {
|
||||
offset = target.getAddress() - a.getAddress() - a.getTotalActionLength();
|
||||
} else {
|
||||
offset = endAddress - a.getAddress() - a.getTotalActionLength();
|
||||
}
|
||||
aIf.setJumpOffset((int) offset);
|
||||
} else if (a instanceof ActionJump) {
|
||||
ActionJump aJump = (ActionJump) a;
|
||||
Action target = jumps.get(a);
|
||||
long offset;
|
||||
if (target != null) {
|
||||
offset = target.getAddress() - a.getAddress() - a.getTotalActionLength();
|
||||
} else {
|
||||
offset = endAddress - a.getAddress() - a.getTotalActionLength();
|
||||
}
|
||||
aJump.setJumpOffset((int) offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateActionStores(ActionList actionList, Map<Action, Action> jumps) {
|
||||
for (Action a : actions) {
|
||||
if (a instanceof ActionStore) {
|
||||
ActionStore aStore = (ActionStore) a;
|
||||
Action nextActionAfterStore = jumps.get(a);
|
||||
Action a1 = a;
|
||||
List<Action> store = new ArrayList<>();
|
||||
while (true) {
|
||||
long address = a1.getAddress() + a1.getTotalActionLength();
|
||||
a1 = actionList.getByAddress(address);
|
||||
if (a1 == null || a1 == nextActionAfterStore) {
|
||||
break;
|
||||
}
|
||||
store.add(a1);
|
||||
}
|
||||
aStore.setStore(store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContainerSizes(Map<Action, List<Action>> containerLastActions) {
|
||||
for (Action a : actions) {
|
||||
if (a instanceof GraphSourceItemContainer) {
|
||||
GraphSourceItemContainer container = (GraphSourceItemContainer) a;
|
||||
List<Action> lastActions = containerLastActions.get(a);
|
||||
long startAddress = a.getAddress() + container.getHeaderSize();
|
||||
for (int j = 0; j < lastActions.size(); j++) {
|
||||
Action lastAction = lastActions.get(j);
|
||||
int length = (int) (lastAction.getAddress() + lastAction.getTotalActionLength() - startAddress);
|
||||
container.setContainerSize(j, length);
|
||||
startAddress += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void expandPushes() {
|
||||
@@ -67,6 +227,9 @@ public class FastActionList {
|
||||
public ActionList toActionList() {
|
||||
ActionList result = new ActionList(actions);
|
||||
updateActionAddressesAndLengths();
|
||||
updateJumps(jumps);
|
||||
updateActionStores(result, jumps);
|
||||
updateContainerSizes(containerLastActions);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,11 @@ public class ActionIf extends Action {
|
||||
|
||||
@Override
|
||||
public void getRef(Set<Long> refs) {
|
||||
refs.add(getAddress() + getTotalActionLength() + offset);
|
||||
refs.add(getTargetAddress());
|
||||
}
|
||||
|
||||
public long getTargetAddress() {
|
||||
return getAddress() + 5 /*getTotalActionLength()*/ + offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -61,7 +61,11 @@ public class ActionJump extends Action {
|
||||
|
||||
@Override
|
||||
public void getRef(Set<Long> refs) {
|
||||
refs.add(getAddress() + getTotalActionLength() + offset);
|
||||
refs.add(getTargetAddress());
|
||||
}
|
||||
|
||||
public long getTargetAddress() {
|
||||
return getAddress() + 5 /*getTotalActionLength()*/ + offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user