diff --git a/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java b/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java
index ccd61fecf..06b865d2e 100644
--- a/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java
+++ b/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java
@@ -1,292 +1,309 @@
-/*
- * Copyright (C) 2010-2014 JPEXS
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package com.jpexs.decompiler.flash.action.model;
-
-import com.jpexs.decompiler.flash.SWF;
-import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
-import com.jpexs.decompiler.flash.action.Action;
-import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
-import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
-import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
-import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
-import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
-import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
-import com.jpexs.decompiler.graph.CompilationException;
-import com.jpexs.decompiler.graph.Graph;
-import com.jpexs.decompiler.graph.GraphSourceItem;
-import com.jpexs.decompiler.graph.GraphSourceItemPos;
-import com.jpexs.decompiler.graph.GraphTargetItem;
-import com.jpexs.decompiler.graph.SourceGenerator;
-import com.jpexs.decompiler.graph.model.LocalData;
-import com.jpexs.helpers.Helper;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class FunctionActionItem extends ActionItem {
-
- public List actions;
- public List constants;
- public String functionName;
- public List paramNames;
- public GraphTargetItem calculatedFunctionName;
- private int regStart;
- private List variables;
-
- public static final int REGISTER_THIS = 1;
- public static final int REGISTER_ARGUMENTS = 2;
- public static final int REGISTER_SUPER = 3;
- public static final int REGISTER_ROOT = 4;
- public static final int REGISTER_PARENT = 5;
- public static final int REGISTER_GLOBAL = 6;
-
- @Override
- public List getAllSubItems() {
- List ret = new ArrayList<>();
- ret.addAll(actions);
- return ret;
- }
-
- public FunctionActionItem() {
- super(null, PRECEDENCE_PRIMARY);
- }
-
- public FunctionActionItem(GraphSourceItem instruction, String functionName, List paramNames, List actions, List constants, int regStart, List variables) {
- super(instruction, PRECEDENCE_PRIMARY);
- this.actions = actions;
- this.constants = constants;
- this.functionName = functionName;
- this.paramNames = paramNames;
- this.regStart = regStart;
- this.variables = variables;
- }
-
- @Override
- public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
- writer.append("function");
- if (calculatedFunctionName != null) {
- writer.append(" ");
- calculatedFunctionName.toStringNoQuotes(writer, localData);
- } else if (!functionName.isEmpty()) {
- writer.append(" ");
- writer.append(functionName);
- }
- writer.spaceBeforeCallParenthesies(paramNames.size());
- writer.append("(");
-
- for (int p = 0; p < paramNames.size(); p++) {
- if (p > 0) {
- writer.append(", ");
- }
- String pname = paramNames.get(p);
- if (pname == null || pname.isEmpty()) {
- pname = new RegisterNumber(regStart + p).translate();
- }
- writer.append(pname);
- }
- writer.append(")").startBlock();
-
- Graph.graphToString(actions, writer, localData);
-
- return writer.endBlock();
- }
-
- @Override
- public List getNeededSources() {
- List ret = super.getNeededSources();
- for (GraphTargetItem ti : actions) {
- ret.addAll(ti.getNeededSources());
- }
- return ret;
- }
-
- @Override
- public boolean needsSemicolon() {
- return false;
- }
-
- @Override
- public boolean isCompileTime(Set dependencies) {
- for (GraphTargetItem a : actions) {
- if (dependencies.contains(a)) {
- return false;
- }
- dependencies.add(a);
- if (!a.isCompileTime(dependencies)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public Object getResult() {
- if (!actions.isEmpty()) {
- if (actions.get(actions.size() - 1) instanceof ReturnActionItem) {
- ReturnActionItem r = (ReturnActionItem) actions.get(actions.size() - 1);
- return r.value.getResult();
- }
- }
- return 0;
- }
-
- @Override
- public boolean needsNewLine() {
- return true;
- }
-
- @Override
- public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
-
- Set usedNames = new HashSet<>();
- for (VariableActionItem v : variables) {
- usedNames.add(v.getVariableName());
- }
-
- List ret = new ArrayList<>();
- ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
- List paramRegs = new ArrayList<>();
- SourceGeneratorLocalData localDataCopy = Helper.deepCopy(localData);
- localDataCopy.inFunction++;
- boolean preloadParentFlag = false;
- boolean preloadRootFlag = false;
- boolean preloadSuperFlag = false;
- boolean preloadArgumentsFlag = false;
- boolean preloadThisFlag = false;
- boolean preloadGlobalFlag = false;
-
- boolean suppressParentFlag = false;
- boolean suppressArgumentsFlag = false;
- boolean suppressThisFlag = false;
-
- boolean needsFun2 = false;
-
- List registerNames = new ArrayList<>();
- registerNames.add("***** ZERO *****");
- if (usedNames.contains("this")) {
- needsFun2 = true;
- preloadThisFlag = true;
- registerNames.add("this");
- } else {
- suppressThisFlag = true;
- }
- if (usedNames.contains("arguments")) {
- preloadArgumentsFlag = true;
- needsFun2 = true;
- registerNames.add("arguments");
- } else {
- suppressArgumentsFlag = true;
- }
- if (usedNames.contains("super")) {
- preloadSuperFlag = true;
- needsFun2 = true;
- registerNames.add("super");
- }
- if (usedNames.contains("_root")) {
- preloadRootFlag = true;
- needsFun2 = true;
- registerNames.add("_root");
- }
- if (usedNames.contains("_parent")) {
- preloadParentFlag = true;
- needsFun2 = true;
- registerNames.add("_parent");
- } else {
- suppressParentFlag = true;
- }
- if (usedNames.contains("_global")) {
- needsFun2 = true;
- preloadGlobalFlag = true;
- registerNames.add("_global");
- }
-
- int preloadedNumber = registerNames.size();
- if (!paramNames.isEmpty()) {
- needsFun2 = true;
- }
- if (localData.inMethod) {
- needsFun2 = true;
- }
- if (localData.inFunction > 1) {
- needsFun2 = true;
- }
- if (needsFun2) {
- for (int i = 0; i < paramNames.size(); i++) {
- paramRegs.add(registerNames.size());
- registerNames.add(paramNames.get(i));
- }
- }
-
- if (actions != null && !actions.isEmpty()) {
- localDataCopy.inFunction++;
-
- for (VariableActionItem v : variables) {
- String varName = v.getVariableName();
- GraphTargetItem stored = v.getStoreValue();
- if (needsFun2) {
- if (v.isDefinition() && !registerNames.contains(varName)) {
- registerNames.add(varName);
- }
- }
-
- if (registerNames.contains(varName)) {
- if (stored != null) {
- v.setBoxedValue(new StoreRegisterActionItem(null, new RegisterNumber(registerNames.indexOf(varName), varName), stored, false));
- } else {
- v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName)));
- }
- } else {
- if (v.isDefinition()) {
- v.setBoxedValue(new DefineLocalActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
- } else {
- if (stored != null) {
- v.setBoxedValue(new SetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
- } else {
- v.setBoxedValue(new GetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName)));
- }
- }
- }
-
- }
- ret.addAll(asGenerator.toActionList(asGenerator.generate(localDataCopy, actions)));
- }
- int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length;
- if (!needsFun2 && paramNames.isEmpty()) {
- ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION));
- } else {
- ret.add(0, new ActionDefineFunction2(functionName,
- preloadParentFlag,
- preloadRootFlag,
- suppressParentFlag,
- preloadSuperFlag,
- suppressArgumentsFlag,
- preloadArgumentsFlag,
- suppressThisFlag,
- preloadThisFlag,
- preloadGlobalFlag,
- registerNames.size(), len, SWF.DEFAULT_VERSION, paramNames, paramRegs));
- }
-
- return ret;
- }
-
- @Override
- public boolean hasReturnValue() {
- return false; //function actually returns itself, but here is false for generator to not add Pop
- }
-}
+/*
+ * Copyright (C) 2010-2014 JPEXS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.jpexs.decompiler.flash.action.model;
+
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
+import com.jpexs.decompiler.flash.action.Action;
+import com.jpexs.decompiler.flash.action.Deobfuscation;
+import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator;
+import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
+import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
+import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
+import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
+import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
+import com.jpexs.decompiler.graph.CompilationException;
+import com.jpexs.decompiler.graph.Graph;
+import com.jpexs.decompiler.graph.GraphSourceItem;
+import com.jpexs.decompiler.graph.GraphSourceItemPos;
+import com.jpexs.decompiler.graph.GraphTargetItem;
+import com.jpexs.decompiler.graph.SourceGenerator;
+import com.jpexs.decompiler.graph.model.LocalData;
+import com.jpexs.helpers.Helper;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class FunctionActionItem extends ActionItem {
+
+ public List actions;
+ public List constants;
+ public String functionName;
+ public List paramNames;
+ public GraphTargetItem calculatedFunctionName;
+ private int regStart;
+ private List variables;
+
+ public static final int REGISTER_THIS = 1;
+ public static final int REGISTER_ARGUMENTS = 2;
+ public static final int REGISTER_SUPER = 3;
+ public static final int REGISTER_ROOT = 4;
+ public static final int REGISTER_PARENT = 5;
+ public static final int REGISTER_GLOBAL = 6;
+
+ @Override
+ public List getAllSubItems() {
+ List ret = new ArrayList<>();
+ ret.addAll(actions);
+ return ret;
+ }
+
+ public FunctionActionItem() {
+ super(null, PRECEDENCE_PRIMARY);
+ }
+
+ public FunctionActionItem(GraphSourceItem instruction, String functionName, List paramNames, List actions, List constants, int regStart, List variables) {
+ super(instruction, PRECEDENCE_PRIMARY);
+ this.actions = actions;
+ this.constants = constants;
+ this.functionName = functionName;
+ this.paramNames = paramNames;
+ this.regStart = regStart;
+ this.variables = variables;
+ }
+
+ @Override
+ public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
+ writer.append("function");
+ if (calculatedFunctionName != null) {
+ writer.append(" ");
+ String fname = calculatedFunctionName.toStringNoQuotes(localData);
+ if(!Deobfuscation.isValidName(fname)){
+ calculatedFunctionName.appendTo(writer, localData); //Use quotes
+ }else{
+ calculatedFunctionName.appendToNoQuotes(writer, localData);
+ }
+ } else if (!functionName.isEmpty()) {
+ writer.append(" ");
+ if(!Deobfuscation.isValidName(functionName)){
+ writer.append("\"");
+ writer.append(Helper.escapeString(functionName));
+ writer.append("\"");
+ }else{
+ writer.append(functionName);
+ }
+ }
+ writer.spaceBeforeCallParenthesies(paramNames.size());
+ writer.append("(");
+
+ for (int p = 0; p < paramNames.size(); p++) {
+ if (p > 0) {
+ writer.append(", ");
+ }
+ String pname = paramNames.get(p);
+ if (pname == null || pname.isEmpty()) {
+ pname = new RegisterNumber(regStart + p).translate();
+ }
+ if(!Deobfuscation.isValidName(pname)){
+ writer.append("\"");
+ writer.append(Helper.escapeString(pname));
+ writer.append("\"");
+ }
+ writer.append(pname);
+ }
+ writer.append(")").startBlock();
+
+ Graph.graphToString(actions, writer, localData);
+
+ return writer.endBlock();
+ }
+
+ @Override
+ public List getNeededSources() {
+ List ret = super.getNeededSources();
+ for (GraphTargetItem ti : actions) {
+ ret.addAll(ti.getNeededSources());
+ }
+ return ret;
+ }
+
+ @Override
+ public boolean needsSemicolon() {
+ return false;
+ }
+
+ @Override
+ public boolean isCompileTime(Set dependencies) {
+ for (GraphTargetItem a : actions) {
+ if (dependencies.contains(a)) {
+ return false;
+ }
+ dependencies.add(a);
+ if (!a.isCompileTime(dependencies)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public Object getResult() {
+ if (!actions.isEmpty()) {
+ if (actions.get(actions.size() - 1) instanceof ReturnActionItem) {
+ ReturnActionItem r = (ReturnActionItem) actions.get(actions.size() - 1);
+ return r.value.getResult();
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean needsNewLine() {
+ return true;
+ }
+
+ @Override
+ public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
+
+ Set usedNames = new HashSet<>();
+ for (VariableActionItem v : variables) {
+ usedNames.add(v.getVariableName());
+ }
+
+ List ret = new ArrayList<>();
+ ActionSourceGenerator asGenerator = (ActionSourceGenerator) generator;
+ List paramRegs = new ArrayList<>();
+ SourceGeneratorLocalData localDataCopy = Helper.deepCopy(localData);
+ localDataCopy.inFunction++;
+ boolean preloadParentFlag = false;
+ boolean preloadRootFlag = false;
+ boolean preloadSuperFlag = false;
+ boolean preloadArgumentsFlag = false;
+ boolean preloadThisFlag = false;
+ boolean preloadGlobalFlag = false;
+
+ boolean suppressParentFlag = false;
+ boolean suppressArgumentsFlag = false;
+ boolean suppressThisFlag = false;
+
+ boolean needsFun2 = false;
+
+ List registerNames = new ArrayList<>();
+ registerNames.add("***** ZERO *****");
+ if (usedNames.contains("this")) {
+ needsFun2 = true;
+ preloadThisFlag = true;
+ registerNames.add("this");
+ } else {
+ suppressThisFlag = true;
+ }
+ if (usedNames.contains("arguments")) {
+ preloadArgumentsFlag = true;
+ needsFun2 = true;
+ registerNames.add("arguments");
+ } else {
+ suppressArgumentsFlag = true;
+ }
+ if (usedNames.contains("super")) {
+ preloadSuperFlag = true;
+ needsFun2 = true;
+ registerNames.add("super");
+ }
+ if (usedNames.contains("_root")) {
+ preloadRootFlag = true;
+ needsFun2 = true;
+ registerNames.add("_root");
+ }
+ if (usedNames.contains("_parent")) {
+ preloadParentFlag = true;
+ needsFun2 = true;
+ registerNames.add("_parent");
+ } else {
+ suppressParentFlag = true;
+ }
+ if (usedNames.contains("_global")) {
+ needsFun2 = true;
+ preloadGlobalFlag = true;
+ registerNames.add("_global");
+ }
+
+ int preloadedNumber = registerNames.size();
+ if (!paramNames.isEmpty()) {
+ needsFun2 = true;
+ }
+ if (localData.inMethod) {
+ needsFun2 = true;
+ }
+ if (localData.inFunction > 1) {
+ needsFun2 = true;
+ }
+ if (needsFun2) {
+ for (int i = 0; i < paramNames.size(); i++) {
+ paramRegs.add(registerNames.size());
+ registerNames.add(paramNames.get(i));
+ }
+ }
+
+ if (actions != null && !actions.isEmpty()) {
+ localDataCopy.inFunction++;
+
+ for (VariableActionItem v : variables) {
+ String varName = v.getVariableName();
+ GraphTargetItem stored = v.getStoreValue();
+ if (needsFun2) {
+ if (v.isDefinition() && !registerNames.contains(varName)) {
+ registerNames.add(varName);
+ }
+ }
+
+ if (registerNames.contains(varName)) {
+ if (stored != null) {
+ v.setBoxedValue(new StoreRegisterActionItem(null, new RegisterNumber(registerNames.indexOf(varName), varName), stored, false));
+ } else {
+ v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName)));
+ }
+ } else {
+ if (v.isDefinition()) {
+ v.setBoxedValue(new DefineLocalActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
+ } else {
+ if (stored != null) {
+ v.setBoxedValue(new SetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
+ } else {
+ v.setBoxedValue(new GetVariableActionItem(null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName)));
+ }
+ }
+ }
+
+ }
+ ret.addAll(asGenerator.toActionList(asGenerator.generate(localDataCopy, actions)));
+ }
+ int len = Action.actionsToBytes(asGenerator.toActionList(ret), false, SWF.DEFAULT_VERSION).length;
+ if (!needsFun2 && paramNames.isEmpty()) {
+ ret.add(0, new ActionDefineFunction(functionName, paramNames, len, SWF.DEFAULT_VERSION));
+ } else {
+ ret.add(0, new ActionDefineFunction2(functionName,
+ preloadParentFlag,
+ preloadRootFlag,
+ suppressParentFlag,
+ preloadSuperFlag,
+ suppressArgumentsFlag,
+ preloadArgumentsFlag,
+ suppressThisFlag,
+ preloadThisFlag,
+ preloadGlobalFlag,
+ registerNames.size(), len, SWF.DEFAULT_VERSION, paramNames, paramRegs));
+ }
+
+ return ret;
+ }
+
+ @Override
+ public boolean hasReturnValue() {
+ return false; //function actually returns itself, but here is false for generator to not add Pop
+ }
+}