Added #2066 AS3 Support for api-versioned SWFs

This commit is contained in:
Jindra Petřík
2023-09-26 21:35:39 +02:00
parent d58d582575
commit cbdc998650
20 changed files with 354 additions and 56 deletions

View File

@@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file.
- AS3 - Show `Embed` tag over asset classes (readonly)
- AS3 - Checkbox for exporting assets embedded using `Embed` (-exportembed in commandline)
- FLA export - AS3 - Using `Embed` tag for DefineBinaryData, images not extending BitmapData
- [#2066] AS3 Support for api-versioned SWFs
### Fixed
- [#2043] StartSound2 tag handling
@@ -3098,6 +3099,7 @@ Major version of SWF to XML export changed to 2.
[#2070]: https://www.free-decompiler.com/flash/issues/2070
[#2073]: https://www.free-decompiler.com/flash/issues/2073
[#2057]: https://www.free-decompiler.com/flash/issues/2057
[#2066]: https://www.free-decompiler.com/flash/issues/2066
[#2043]: https://www.free-decompiler.com/flash/issues/2043
[#2017]: https://www.free-decompiler.com/flash/issues/2017
[#2052]: https://www.free-decompiler.com/flash/issues/2052

View File

@@ -128,8 +128,9 @@ public class ScriptPack extends AS3ClassTreeItem {
public Trait getPublicTrait() {
for (int t : traitIndices) {
Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
//Namespace ns = name.getNamespace(abc.constants);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
return abc.script_info.get(scriptIndex).traits.traits.get(t);
}
}
@@ -205,8 +206,8 @@ public class ScriptPack extends AS3ClassTreeItem {
for (int t : traitIndices) {
Trait trait = traits.get(t);
Multiname name = trait.getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
trait.convertPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, scopeStack);
} else {
trait.convert(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, scopeStack);
@@ -256,8 +257,8 @@ public class ScriptPack extends AS3ClassTreeItem {
writer.startTrait(t);
//}
Multiname name = trait.getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
trait.toStringPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
} else {
trait.toString(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);

View File

@@ -335,9 +335,10 @@ public final class AbcIndexing {
this.type = type;
if (scriptIndex != null) {
for (Trait t : abc.script_info.get(scriptIndex).traits.traits) {
Namespace ns = t.getName(abc).getNamespace(abc.constants);
if (ns.kind == Namespace.KIND_PACKAGE) {
pkg = ns.getName(abc.constants);
Multiname m = t.getName(abc);
int nskind = m.getSimpleNamespaceKind(abc.constants);
if (nskind == Namespace.KIND_PACKAGE) {
pkg = m.getSimpleNamespaceName(abc.constants);
}
}
}
@@ -818,7 +819,7 @@ public final class AbcIndexing {
continue;
}
ClassInfo ci = abc.class_info.get(tc.class_info);
int nsKind = abc.constants.getMultiname(tc.name_index).getNamespace(abc.constants).kind;
int nsKind = abc.constants.getMultiname(tc.name_index).getSimpleNamespaceKind(abc.constants);
Integer classScriptIndex = nsKind == Namespace.KIND_PACKAGE ? null : i;
ClassIndex cindex = new ClassIndex(tc.class_info, abc, null, classScriptIndex);
addedClasses.add(cindex);

View File

@@ -187,7 +187,7 @@ public class InstanceInfo {
String modifiers;
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
modifiers = ns.getPrefix(abc);
modifiers = ns.getPrefix();
if (!allowPrivate && modifiers.equals("private")) {
modifiers = "";
}

View File

@@ -24,8 +24,11 @@ import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
*
@@ -410,19 +413,26 @@ public class Multiname {
if (cached != null) {
return cached;
}
Namespace ns = getNamespace(constants);
if (ns == null) {
NamespaceSet nss = getNamespaceSet(constants);
if (nss != null) {
if (nss.namespaces.length == 1) {
ns = constants.getNamespace(nss.namespaces[0]);
DottedChain nsName = getSimpleNamespaceName(constants);
if (nsName == null) {
Namespace ns = getNamespace(constants);
if (ns == null) {
NamespaceSet nss = getNamespaceSet(constants);
if (nss != null) {
if (nss.namespaces.length == 1) {
ns = constants.getNamespace(nss.namespaces[0]);
}
}
}
if (ns != null) {
nsName = ns.getName(constants);
}
}
String name = getName(constants, null, true, false);
DottedChain ret;
if (ns != null) {
ret = ns.getName(constants).add(name, withSuffix ? getNamespaceSuffix() : "");
if (nsName != null) {
ret = nsName.add(name, withSuffix ? getNamespaceSuffix() : "");
} else {
ret = new DottedChain(new String[]{name}, new String[]{withSuffix ? getNamespaceSuffix() : ""});
}
@@ -437,6 +447,60 @@ public class Multiname {
return constants.getNamespace(namespace_index);
}
}
/**
* Gets simple namespace name as dottedchain. Ignores swf api versioning.
* @param constants
* @return
*/
public DottedChain getSimpleNamespaceName(AVM2ConstantPool constants) {
if (hasOwnNamespace()) {
if (namespace_index == 0 || namespace_index == -1) {
return DottedChain.EMPTY;
}
return getNamespace(constants).getName(constants);
}
if (hasOwnNamespaceSet()) {
NamespaceSet nss = getNamespaceSet(constants);
if (nss == null) {
return null;
}
return nss.getNonversionedName(constants);
}
return null;
}
/**
* Gets simplpe namespace kind. Ignores swf api versioning.
* @param constants
* @return
*/
public int getSimpleNamespaceKind(AVM2ConstantPool constants) {
if (hasOwnNamespace()) {
if (namespace_index == 0 || namespace_index == -1) {
return 0;
}
return getNamespace(constants).kind;
}
if (hasOwnNamespaceSet()) {
NamespaceSet nss = getNamespaceSet(constants);
if (nss == null) {
return 0;
}
return nss.getNonversionedKind(constants);
}
return 0;
}
public List<Integer> getApiVersions(AVM2ConstantPool constants) {
if (hasOwnNamespace()) {
return new ArrayList<>();
}
if (hasOwnNamespaceSet()) {
return getNamespaceSet(constants).getApiVersions(constants);
}
return new ArrayList<>();
}
public NamespaceSet getNamespaceSet(AVM2ConstantPool constants) {
if (namespace_set_index == 0) {

View File

@@ -26,6 +26,10 @@ import com.jpexs.decompiler.graph.DottedChain;
* @author JPEXS
*/
public class Namespace {
public static final int MIN_API_MARK = 0xE000;
public static final int MAX_API_MARK = 0xF8FF;
public static final int KIND_NAMESPACE = 8;
@@ -107,7 +111,18 @@ public class Namespace {
return kindStr + (nameStr == null || nameStr.isEmpty() ? "" : " " + nameStr);
}
public String getPrefix(ABC abc) {
public String getPrefix() {
String kindStr = "?";
for (int k = 0; k < nameSpaceKinds.length; k++) {
if (nameSpaceKinds[k] == kind) {
kindStr = namePrefixes[k];
break;
}
}
return kindStr;
}
public static String getPrefix(int kind) {
String kindStr = "?";
for (int k = 0; k < nameSpaceKinds.length; k++) {
if (nameSpaceKinds[k] == kind) {

View File

@@ -18,6 +18,11 @@ package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.graph.DottedChain;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
@@ -47,4 +52,78 @@ public class NamespaceSet {
}
return sb.toString();
}
public List<Integer> getApiVersions(AVM2ConstantPool constants) {
Set<String> namespaceNames = new HashSet<>();
Set<Integer> namespaceKinds = new HashSet<>();
List<Integer> apiVersions = new ArrayList<>();
for (int n:namespaces) {
Namespace ns = constants.getNamespace(n);
String nsName = ns.getRawName(constants);
if (nsName != null && nsName.length() > 0) {
int lastChar = nsName.codePointAt(nsName.length() - 1);
if (lastChar >= Namespace.MIN_API_MARK && lastChar <= Namespace.MAX_API_MARK) {
namespaceNames.add(nsName.substring(0, nsName.length() - 1));
namespaceKinds.add(ns.kind);
int apiVersion = lastChar - Namespace.MIN_API_MARK;
if (apiVersion != 0) {
apiVersions.add(apiVersion);
}
} else {
return new ArrayList<>();
}
}
}
if (namespaceNames.size() != 1) {
return new ArrayList<>();
}
if (namespaceKinds.size() != 1) {
return new ArrayList<>();
}
return apiVersions;
}
public int getNonversionedKind(AVM2ConstantPool constants) {
Set<String> namespaceNames = new HashSet<>();
Set<Integer> namespaceKinds = new HashSet<>();
for (int n:namespaces) {
Namespace ns = constants.getNamespace(n);
String nsName = ns.getRawName(constants);
if (nsName != null && nsName.length() > 0) {
int lastChar = nsName.codePointAt(nsName.length() - 1);
if (lastChar >= Namespace.MIN_API_MARK && lastChar <= Namespace.MAX_API_MARK) {
namespaceNames.add(nsName.substring(0, nsName.length() - 1));
namespaceKinds.add(ns.kind);
} else {
return 0;
}
}
}
if (namespaceNames.size() != 1) {
return 0;
}
if (namespaceKinds.size() != 1) {
return 0;
}
return namespaceKinds.iterator().next();
}
public DottedChain getNonversionedName(AVM2ConstantPool constants) {
Set<String> namespaceNames = new HashSet<>();
for (int n:namespaces) {
String nsName = constants.getNamespace(n).getRawName(constants);
if (nsName != null && nsName.length() > 0) {
int lastChar = nsName.codePointAt(nsName.length() - 1);
if (lastChar >= Namespace.MIN_API_MARK && lastChar <= Namespace.MAX_API_MARK) {
namespaceNames.add(nsName.substring(0, nsName.length() - 1));
} else {
return null;
}
}
}
if (namespaceNames.size() != 1) {
return null;
}
return DottedChain.parseNoSuffix(namespaceNames.iterator().next());
}
}

View File

@@ -97,19 +97,19 @@ public class ScriptInfo {
for (int j = 0; j < traits.traits.size(); j++) {
Trait t = traits.traits.get(j);
Multiname name = t.getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if (!((ns.kind == Namespace.KIND_PACKAGE_INTERNAL)
|| (ns.kind == Namespace.KIND_PACKAGE))) {
int nskind = name.getSimpleNamespaceKind(abc.constants);
if (!((nskind == Namespace.KIND_PACKAGE_INTERNAL)
|| (nskind == Namespace.KIND_PACKAGE))) {
otherTraits.add(j);
}
}
for (int j = 0; j < traits.traits.size(); j++) {
Trait t = traits.traits.get(j);
Multiname name = t.getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL)
|| (ns.kind == Namespace.KIND_PACKAGE)) {
DottedChain packageName = ns.getName(abc.constants); // assume not null package
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE_INTERNAL)
|| (nskind == Namespace.KIND_PACKAGE)) {
DottedChain packageName = name.getSimpleNamespaceName(abc.constants); // assume not null package
String objectName = name.getName(abc.constants, null, true, false);
String namespaceSuffix = name.getNamespaceSuffix();
List<Integer> traitIndices = new ArrayList<>();
@@ -134,9 +134,8 @@ public class ScriptInfo {
for (int traitIndex : otherTraits) {
Trait t = traits.traits.get(traitIndex);
Multiname name = t.getName(abc);
Namespace ns = name.getNamespace(abc.constants);
DottedChain packageName = ns.getName(abc.constants);
DottedChain packageName = name.getSimpleNamespaceName(abc.constants);
String objectName = name.getName(abc.constants, null, true, false);
String namespaceSuffix = name.getNamespaceSuffix();

View File

@@ -170,14 +170,15 @@ public abstract class Trait implements Cloneable, Serializable {
}
protected DottedChain getPackage(ABC abc) {
return getName(abc).getNamespace(abc.constants).getName(abc.constants);
return getName(abc).getSimpleNamespaceName(abc.constants);
}
public void getDependencies(AbcIndexing abcIndex, int scriptIndex, int classIndex, boolean isStatic, String ignoredCustom, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
if (ignoredCustom == null) {
Namespace n = getName(abc).getNamespace(abc.constants);
if (n.kind == Namespace.KIND_NAMESPACE) {
ignoredCustom = n.getName(abc.constants).toRawString();
Multiname m = getName(abc);
int nskind = m.getSimpleNamespaceKind(abc.constants);
if (nskind == Namespace.KIND_NAMESPACE) {
ignoredCustom = m.getSimpleNamespaceName(abc.constants).toRawString();
}
}
DependencyParser.parseDependenciesFromMultiname(abcIndex, ignoredCustom, abc, dependencies, getName(abc), ignorePackage, fullyQualifiedNames, DependencyType.NAMESPACE);
@@ -199,8 +200,8 @@ public abstract class Trait implements Cloneable, Serializable {
boolean publicProtectedOnly = isParent;
for (Trait it : abc.instance_info.get(classIndex).instance_traits.traits) {
if (publicProtectedOnly) {
Namespace ns = it.getName(abc).getNamespace(abc.constants);
if (ns.kind != Namespace.KIND_PACKAGE && ns.kind != Namespace.KIND_PROTECTED) {
int nskind = it.getName(abc).getSimpleNamespaceKind(abc.constants);
if (nskind != Namespace.KIND_PACKAGE && nskind != Namespace.KIND_PROTECTED) {
continue;
}
}
@@ -208,8 +209,8 @@ public abstract class Trait implements Cloneable, Serializable {
}
for (Trait ct : abc.class_info.get(classIndex).static_traits.traits) {
if (publicProtectedOnly) {
Namespace ns = ct.getName(abc).getNamespace(abc.constants);
if (ns.kind != Namespace.KIND_PACKAGE && ns.kind != Namespace.KIND_STATIC_PROTECTED) {
int nskind = ct.getName(abc).getSimpleNamespaceKind(abc.constants);
if (nskind != Namespace.KIND_PACKAGE && nskind != Namespace.KIND_STATIC_PROTECTED) {
continue;
}
}
@@ -249,9 +250,10 @@ public abstract class Trait implements Cloneable, Serializable {
//imports
List<Dependency> dependencies = new ArrayList<>();
String customNs = null;
Namespace ns = getName(abc).getNamespace(abc.constants);
if (ns.kind == Namespace.KIND_NAMESPACE) {
customNs = ns.getName(abc.constants).toRawString();
Multiname multiname = getName(abc);
int nskind = multiname.getSimpleNamespaceKind(abc.constants);
if (nskind == Namespace.KIND_NAMESPACE) {
customNs = multiname.getSimpleNamespaceName(abc.constants).toRawString();
}
getDependencies(abcIndex, scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, new ArrayList<>());
@@ -367,6 +369,15 @@ public abstract class Trait implements Cloneable, Serializable {
writer.append("]");
writer.newLine();
}
getApiVersions(abc, writer);
return writer;
}
public final GraphTextWriter getApiVersions(ABC abc, GraphTextWriter writer) {
List<Integer> apiVersions = abc.constants.getMultiname(name_index).getApiVersions(abc.constants);
for(int version:apiVersions) {
writer.appendNoHilight("[API(\"" + version + "\")]").newLine();
}
return writer;
}
@@ -384,21 +395,21 @@ public abstract class Trait implements Cloneable, Serializable {
DottedChain dc = abc.findCustomNs(m.namespace_index);
String nsname = dc != null ? dc.getLast() : null;
Namespace ns = m.getNamespace(abc.constants);
int nskind = m.getSimpleNamespaceKind(abc.constants);
if (insideInterface) {
//no namespace identifier
} else if (ns.kind == Namespace.KIND_NAMESPACE && nsname == null) {
} else if (nskind == Namespace.KIND_NAMESPACE && nsname == null) {
writer.append("§§namespace(\"");
writer.append(Helper.escapeActionScriptString(ns.getRawName(abc.constants)));
writer.append(Helper.escapeActionScriptString(m.getSimpleNamespaceName(abc.constants).toRawString()));
writer.append("\") ");
} else if (nsname != null) {
String identifier = IdentifiersDeobfuscation.printIdentifier(true, nsname);
if (identifier != null && !identifier.isEmpty()) {
writer.appendNoHilight(identifier).appendNoHilight(" ");
}
} else if (ns != null) {
String nsPrefix = ns.getPrefix(abc);
} else if (nskind != 0) {
String nsPrefix = Namespace.getPrefix(nskind);
if (nsPrefix != null && !nsPrefix.isEmpty()) {
writer.appendNoHilight(nsPrefix).appendNoHilight(" ");
}
@@ -508,9 +519,10 @@ public abstract class Trait implements Cloneable, Serializable {
}
public GraphTextWriter toStringPackaged(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, boolean insideInterface) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants).toPrintableString(true);
Multiname name = abc.constants.getMultiname(name_index);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = name.getSimpleNamespaceName(abc.constants).toPrintableString(true);
writer.appendNoHilight("package");
if (!nsname.isEmpty()) {
writer.appendNoHilight(" " + nsname); //assume not null name
@@ -524,9 +536,10 @@ public abstract class Trait implements Cloneable, Serializable {
}
public void convertPackaged(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants).toPrintableString(true);
Multiname name = abc.constants.getMultiname(name_index);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = name.getSimpleNamespaceName(abc.constants).toPrintableString(true);
convert(abcIndex, parent, convertData, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack);
}
}

View File

@@ -139,7 +139,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
String instanceInfoName = instanceInfoMultiname.getName(abc.constants, fullyQualifiedNames, false, true);
getMetaData(parent, convertData, abc, writer);
boolean allowEmbed = true;
if (convertData.exportEmbedFlaMode) {

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
@@ -70,9 +71,10 @@ public class TraitMethodGetterSetter extends Trait {
super.getDependencies(abcIndex, scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, fullyQualifiedNames);
if (customNs == null) {
Namespace n = getName(abc).getNamespace(abc.constants);
if (n.kind == Namespace.KIND_NAMESPACE) {
customNs = n.getName(abc.constants).toRawString();
Multiname m = getName(abc);
int nskind = m.getSimpleNamespaceKind(abc.constants);
if (nskind == Namespace.KIND_NAMESPACE) {
customNs = m.getSimpleNamespaceName(abc.constants).toRawString();
}
}
//if (method_info != 0)

Binary file not shown.

View File

@@ -0,0 +1,50 @@
const int as3_versioned_abc_length = 718;
const int as3_versioned_abc_method_count = 0;
const int as3_versioned_abc_class_count = 3;
const int as3_versioned_abc_script_count = 2;
const unsigned char as3_versioned_abc_data[718] = {
0x10, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x18, 0x00, 0x04, 0x76, 0x6f, 0x69, 0x64, 0x06, 0x4f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x05, 0x6d, 0x79, 0x70,
0x6b, 0x67, 0x07, 0x4d, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x0d, 0x6d, 0x79, 0x70, 0x6b, 0x67,
0x3a, 0x4d, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x04, 0x74, 0x65, 0x73, 0x74, 0x03, 0xee, 0x80,
0x80, 0x08, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x36, 0x36, 0x32, 0x03, 0xee, 0x8a, 0x96, 0x08, 0x74,
0x65, 0x73, 0x74, 0x5f, 0x36, 0x37, 0x34, 0x03, 0xee, 0x8a, 0xa2, 0x0c, 0x74, 0x65, 0x73, 0x74,
0x5f, 0x36, 0x36, 0x32, 0x5f, 0x36, 0x37, 0x34, 0x03, 0x41, 0x53, 0x33, 0x21, 0x68, 0x74, 0x74,
0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x53,
0x33, 0x2f, 0x32, 0x30, 0x30, 0x36, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x03, 0x4e,
0x61, 0x4e, 0x08, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x09, 0x75, 0x6e, 0x64, 0x65,
0x66, 0x69, 0x6e, 0x65, 0x64, 0x08, 0x6d, 0x79, 0x70, 0x6b, 0x67, 0xee, 0x8a, 0x95, 0x08, 0x6d,
0x79, 0x70, 0x6b, 0x67, 0xee, 0x8a, 0x96, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x0b, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x11, 0x16, 0x01, 0x18, 0x03, 0x18, 0x04,
0x16, 0x05, 0x18, 0x07, 0x16, 0x09, 0x16, 0x0b, 0x16, 0x0d, 0x08, 0x10, 0x16, 0x14, 0x16, 0x15,
0x05, 0x00, 0x05, 0x00, 0x17, 0x05, 0x1a, 0x07, 0x17, 0x01, 0x0b, 0x01, 0x06, 0x01, 0x07, 0x01,
0x08, 0x02, 0x07, 0x08, 0x02, 0x0a, 0x0b, 0x07, 0x01, 0x0c, 0x0d, 0x04, 0x0e, 0x05, 0x0f, 0x01,
0x01, 0x03, 0x01, 0x0d, 0x10, 0x01, 0x04, 0x04, 0x01, 0x0d, 0x04, 0x0e, 0x1a, 0x07, 0x01, 0x02,
0x07, 0x01, 0x03, 0x07, 0x01, 0x04, 0x07, 0x04, 0x06, 0x09, 0x08, 0x01, 0x09, 0x0a, 0x02, 0x09,
0x0c, 0x03, 0x09, 0x0e, 0x04, 0x09, 0x0f, 0x01, 0x09, 0x11, 0x01, 0x09, 0x12, 0x01, 0x09, 0x13,
0x01, 0x09, 0x03, 0x01, 0x09, 0x04, 0x01, 0x09, 0x06, 0x05, 0x09, 0x16, 0x06, 0x09, 0x0c, 0x06,
0x09, 0x03, 0x07, 0x09, 0x04, 0x07, 0x09, 0x03, 0x08, 0x09, 0x06, 0x09, 0x09, 0x03, 0x0a, 0x07,
0x01, 0x11, 0x07, 0x01, 0x12, 0x07, 0x01, 0x13, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x09, 0x02, 0x00,
0x01, 0x00, 0x03, 0x02, 0x09, 0x03, 0x00, 0x03, 0x00, 0x04, 0x02, 0x09, 0x05, 0x00, 0x09, 0x04,
0x05, 0x01, 0x02, 0x05, 0x06, 0x01, 0x03, 0x06, 0x07, 0x01, 0x04, 0x07, 0x08, 0x01, 0x05, 0x08,
0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x0b, 0x04, 0x09, 0x06, 0x01, 0x00, 0x09, 0x08, 0x0a,
0x06, 0x02, 0x03, 0x01, 0x06, 0x0b, 0x06, 0x03, 0x03, 0x02, 0x06, 0x0c, 0x06, 0x04, 0x00, 0x00,
0x0a, 0x03, 0x0d, 0x04, 0x00, 0x00, 0x0e, 0x04, 0x00, 0x01, 0x0f, 0x04, 0x00, 0x02, 0x0c, 0x00,
0x01, 0x01, 0x02, 0x03, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x04, 0x03,
0xd0, 0x30, 0x47, 0x00, 0x00, 0x02, 0x01, 0x01, 0x03, 0x04, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00,
0x03, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, 0x00, 0x00, 0x04, 0x01,
0x01, 0x03, 0x04, 0x03, 0xd0, 0x30, 0x47, 0x00, 0x00, 0x05, 0x02, 0x01, 0x04, 0x05, 0x0a, 0xd0,
0x30, 0x5d, 0x10, 0x2c, 0x17, 0x4f, 0x10, 0x01, 0x47, 0x00, 0x00, 0x06, 0x02, 0x01, 0x04, 0x05,
0x0a, 0xd0, 0x30, 0x5d, 0x10, 0x2c, 0x17, 0x4f, 0x10, 0x01, 0x47, 0x00, 0x00, 0x07, 0x02, 0x01,
0x04, 0x05, 0x0a, 0xd0, 0x30, 0x5d, 0x10, 0x2c, 0x17, 0x4f, 0x10, 0x01, 0x47, 0x00, 0x00, 0x08,
0x02, 0x01, 0x04, 0x05, 0x0e, 0xd0, 0x30, 0xd0, 0x4f, 0x11, 0x00, 0x5d, 0x10, 0x2c, 0x17, 0x4f,
0x10, 0x01, 0x47, 0x00, 0x00, 0x09, 0x01, 0x01, 0x04, 0x05, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00,
0x47, 0x00, 0x00, 0x0a, 0x02, 0x01, 0x01, 0x03, 0x22, 0xd0, 0x30, 0x5d, 0x12, 0x20, 0x58, 0x00,
0x68, 0x02, 0x5d, 0x13, 0x60, 0x02, 0x30, 0x60, 0x14, 0x58, 0x01, 0x1d, 0x68, 0x03, 0x5d, 0x15,
0x60, 0x02, 0x30, 0x60, 0x16, 0x58, 0x02, 0x1d, 0x68, 0x04, 0x47, 0x00, 0x00, 0x0b, 0x03, 0x01,
0x01, 0x02, 0x19, 0xd0, 0x30, 0x65, 0x00, 0x24, 0x00, 0x2a, 0xa3, 0x68, 0x17, 0x65, 0x00, 0x24,
0x01, 0x24, 0x00, 0xa3, 0x68, 0x18, 0x65, 0x00, 0x21, 0x68, 0x19, 0x47, 0x00, 0x00 };

View File

@@ -0,0 +1,10 @@
const int abcclass_Object = 0;
const int abcclass_Number = 1;
const int abcclass_mypkg_MyClass = 2;
const int abcpackage_Toplevel_as = 0;
const int abcpackage_stubs_as = 1;
extern const int as3_versioned_abc_length;
extern const int as3_versioned_abc_method_count;
extern const int as3_versioned_abc_class_count;
extern const int as3_versioned_abc_script_count;
extern const unsigned char as3_versioned_abc_data[];

View File

@@ -0,0 +1,7 @@
@echo off
set COMPILERKIND=flex
set SWFNAME=as3_versioned
rem call c:\air\bin\mxmlc.bat -debug=true -builtin -apiversioning -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
java -classpath c:\flex\lib\asc.jar macromedia.asc.embedding.ScriptCompiler -optimize -builtin -apiversioning -outdir bin/ -out as3_versioned src/stubs.as src/Toplevel.as
pause
rem -warnings=false

View File

@@ -0,0 +1,4 @@
package {
public class Number {
}
}

View File

@@ -0,0 +1,6 @@
package
{
public class Object
{
}
}

View File

@@ -0,0 +1,9 @@
package {
public namespace AS3 = "http://adobe.com/AS3/2006/builtin";
public const NaN: Number = 0 / 0;
public const Infinity: Number = 1 / 0;
public const undefined = void 0;
}

View File

@@ -0,0 +1,33 @@
package mypkg
{
[API("661")]
[API("662")]
public class MyClass
{
public function test(): void
{
trace("Hello world");
}
[API("662")]
public function test_662(): void
{
trace("Hello world");
}
[API("674")]
public function test_674(): void
{
trace("Hello world");
}
[API("662")]
[API("674")]
public function test_662_674(): void
{
this.test_674();
trace("Hello world");
}
}
}

View File

@@ -0,0 +1,3 @@
include "Object.as"
include "Number.as"
include "mypkg/MyClass.as"