/// <summary> /// Compiles <see cref="IMethod.Implements"/> methods. /// </summary> /// <param name="method"></param> /// <param name="instance"></param> /// <param name="abcMethod"></param> private void BuildImplementedMethods(IMethod method, AbcInstance instance, AbcMethod abcMethod) { var impls = method.Implements; if (impls == null) { return; } int n = impls.Count; if (n <= 0) { return; } //NOTE: To avoid conflict with name of explicit implementation method has the same name as iface method if (method.IsExplicitImplementation) { Build(impls[0]); return; } if (n == 1 && !abcMethod.IsOverride) { Build(impls[0]); return; } foreach (var ifaceMethod in impls) { var ifaceAbcMethod = BuildAbcMethod(ifaceMethod); BuildExplicitImplementation(instance, abcMethod, ifaceMethod, ifaceAbcMethod); } }
private void BuildCompiledMethods(AbcInstance instance, IType type) { if (instance == null) { throw new ArgumentNullException("instance"); } if (type == null) { throw new ArgumentNullException("type"); } _generator.ArrayImpl.ImplementInterface(type); //Define Compiled Interface Methods foreach (var iface in instance.Implements) { BuildCompiledMethods(instance, type, iface); } //Define Override Methods for already Compiled Base Methods var super = instance.BaseInstance; while (super != null) { BuildCompiledMethods(instance, type, super); super = super.BaseInstance; } }
private static bool IsStyleMixin(AbcInstance instance, bool strict) { if (instance.Traits.Count > 0) { return(false); } var klass = instance.Class; if (klass.Traits.Count == 0) { return(false); } var trait = klass.Traits.FindMethod("init"); if (trait == null) { return(false); } if (trait.Method.Parameters.Count != 1) { return(false); } if (!strict) { return(true); } var type = trait.Method.Parameters[0].Type; if (type == null) { return(false); } return(type.FullName == MX.IFlexModuleFactory); }
//TODO: Add options to control level of reflection support public AbcMethod Define_Assembly_GetTypeNum(IMethod method, AbcInstance instance) { _emitReflection = true; var m = instance.DefineMethod(_generator.MethodBuilder.SigOf(method), null); _generator.AddLateMethod( m, code => { #if DEBUG DebugService.LogInfo("FinishInitTypes started"); #endif DefineInitTypeMethods(); DefineGetTypeIdMethods(); code.PushInt(_initTypes.Count); code.ReturnValue(); #if DEBUG DebugService.LogInfo("FinishInitTypes succeeded"); #endif } ); return(m); }
private static void AddInterfaces(AbcInstance instance, IType type, IList <AbcMultiname> ifaceNames) { if (ifaceNames == null) { return; } if (type.Interfaces == null) { return; } int n = type.Interfaces.Count; for (int i = 0; i < n; ++i) { var iface = type.Interfaces[i]; var ifaceName = ifaceNames[i]; var ifaceInstance = iface.AbcInstance(); if (ifaceInstance != null) { ifaceInstance.Implementations.Add(instance); instance.Implements.Add(ifaceInstance); } instance.Interfaces.Add(ifaceName); } }
public static void Implement(AbcInstance instance, IType iface) { foreach (var method in iface.Methods.Where(x => x.AbcMethod() != null)) { Build(instance, method); } }
public static InlineCall Build(AbcFile abc, AbcInstance instance, IMethod method) { if (instance != null && instance.IsNative) { var mn = instance.Name; string name = mn.FullName; InlineCodeProvider provider; if (AvmInlines.TryGetValue(name, out provider)) { return(provider.GetImplementation(abc, method)); } if (name.StartsWith(AS3.Vector.FullName)) { return(AvmVectorInlines.Get(abc, method)); } } var type = method.DeclaringType; if (type.Data is IVectorType) { return(AvmVectorInlines.Get(abc, method)); } return(GetImpl(abc, type, method)); }
private AbcMethod BuildGetterImpl(IMethod method, AbcInstance instance) { if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } if (method.Name != CLRNames.Array.Getter) { return(null); } //string name = "Get" + NameUtil.GetParamsString(method); var name = _generator.MethodBuilder.DefineQName(method); return(instance.DefineMethod( Sig.@this(name, method.Type, method), code => { code.LoadThis(); ToFlatIndex(code, method.Parameters.Count, true); code.GetArrayElem(method.Type, false); code.ReturnValue(); })); }
private AbcMethod BuildSetterImpl(IMethod method, AbcInstance instance) { if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } if (method.Name != CLRNames.Array.Setter) { return(null); } var name = _generator.MethodBuilder.DefineQName(method); return(instance.DefineMethod( Sig.@this(name, method.Type, method), code => { int n = method.Parameters.Count; code.LoadThis(); ToFlatIndex(code, n, false); code.GetLocal(n); //value code.SetArrayElem(false); code.ReturnVoid(); })); }
/// <summary> /// Create, initialize and put on stack PropertyInfo object /// </summary> /// <param name="code"></param> /// <param name="prop"></param> private void NewPropertyInfo(AbcCode code, AbcInstance instance, IProperty prop, int varProp) { var type = _generator.Corlib.GetType(CorlibTypeId.PropertyInfo); var ctor = type.FindConstructor(0); if (ctor == null) { throw new InvalidOperationException(".ctor not found"); } code.NewObject(ctor, () => { }); code.SetLocal(varProp); code.GetLocal(varProp); code.PushString(prop.Name); code.SetField(FieldId.PropertyInfo_Name); code.GetLocal(varProp); code.PushTypeId(prop.Type); code.SetField(FieldId.PropertyInfo_Type); SetAccessor(code, prop.Getter, FieldId.PropertyInfo_Getter, varProp); SetAccessor(code, prop.Setter, FieldId.PropertyInfo_Setter, varProp); InitCustomAttributes(code, instance, prop, varProp); code.GetLocal(varProp); }
private static XElement ToXml(this AbcInstance instance) { var xInstance = new XElement("instance"); xInstance.Add(new XAttribute("name", instance.Name.ToXml())); if (instance.SuperName != null && instance.SuperName != AbcMultiname.Void) { xInstance.Add(new XAttribute("extends", instance.SuperName.ToXml())); } if (instance.Traits.Count > 0) { xInstance.Add(instance.Traits.ToXml()); } if (instance.Interfaces.Count > 0) { var xInterfaces = new XElement("implements"); foreach (var inter in instance.Interfaces) { xInterfaces.Add(new XElement("interface", inter)); } xInstance.Add(xInterfaces); } return(xInstance); }
private void NewParameterInfo(AbcCode code, AbcInstance instance, IParameter param, int varMethod, int varParam) { var pitype = _generator.Corlib.GetType(CorlibTypeId.ParameterInfo); if (param.Type == null) { throw new InvalidOperationException("Parametr type is null"); } var ctor = pitype.FindConstructor(0); if (ctor == null) { throw new InvalidOperationException(".ctor not found"); } code.NewObject(ctor, () => { }); code.SetLocal(varParam); code.GetLocal(varParam); code.PushInt(GetTypeId(param.Type)); code.SetField(FieldId.ParameterInfo_ClassImpl); code.GetLocal(varParam); code.PushString(param.Name); code.SetField(FieldId.ParameterInfo_NameImpl); code.GetLocal(varParam); code.GetLocal(varMethod); code.SetField(FieldId.ParameterInfo_MemberImpl); InitCustomAttributes(code, instance, param, varParam); code.GetLocal(varParam); }
private AbcMethod DefineCustomAttributesInitializer(AbcInstance instance, ICustomAttributeProvider provider) { instance = FixInstance(instance); var provname = provider.GetQName(); if (provname == null) { provname = NameDummyCounter.ToString(); ++NameDummyCounter; } var name = _generator.Abc.DefineName(QName.PfxPublic("init_custom_attrs_" + provname)); return(instance.DefineMethod( Sig.@static(name, _generator.Corlib.Array.Instance), code => { const int arr = 1; const int varAttr = 2; code.NewArray(arr, SystemTypes.Object, provider.CustomAttributes, attr => NewAttribute(code, attr, varAttr)); code.ReturnValue(); })); }
private static void BuildExplicitImplementation(AbcInstance instance, AbcMethod abcMethod, IMethod ifaceMethod, AbcMethod ifaceAbcMethod) { instance.DefineMethod( Sig.@from(ifaceAbcMethod), code => { code.LoadThis(); code.LoadArguments(ifaceMethod); code.Call(abcMethod); if (ifaceAbcMethod.IsVoid) { code.ReturnVoid(); } else { code.ReturnValue(); } }, m => { var isOverride = instance.BaseInstances() .FirstOrDefault(x => x.Traits.Contains(ifaceAbcMethod.TraitName, ifaceAbcMethod.Trait.Kind)) != null; m.Trait.IsOverride = isOverride; OverrideExplicitImplsInSubclasses(instance, ifaceAbcMethod); }); }
private IMethodCall Resolve(IMethod method, AbcInstance instance) { var inlineCall = InlineCodeGenerator.Build(Abc, instance, method); if (inlineCall != null) { return(inlineCall); } if (method.CodeType == MethodCodeType.Native) { return(ThrowOrDefineNotImplCall(method, instance)); } if (method.IsInternalCall) { return(ResolveInternalCall(method, instance)); } if (method.CodeType == MethodCodeType.Runtime) { return(ResolveRuntimeCode(method, instance)); } return(null); }
private AbcMethod BuildAddressImpl(IMethod method, AbcInstance instance) { if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } if (method.Name != CLRNames.Array.Address) { return(null); } var elemPtr = _generator.Pointers.ElemPtr.Instance; string name = "GetAddr_" + method.GetParametersSignature(Runtime.Avm); return(instance.DefineMethod( Sig.@this(name, elemPtr.Name, method), code => { code.Getlex(elemPtr); code.LoadThis(); //arr ToFlatIndex(code, method.Parameters.Count, true); code.Construct(2); code.ReturnValue(); })); }
static void DumpInstanceCore(AbcInstance instance, string path, bool withScript) { try { using (var writer = Utils.CreateXmlWriter(path)) { writer.WriteStartDocument(); writer.WriteStartElement("abc"); instance.DumpXml(writer); if (withScript) { var abc = instance.Abc; if (abc != null) { var script = instance.Script; if (script != null) { script.DumpXml(writer); } } } writer.WriteEndElement(); writer.WriteEndDocument(); } } catch (Exception e) { Console.WriteLine("Unable to dump instance {0}", instance.FullName); Console.WriteLine(e); } }
public AbcMethod BuildSpecMethod(IMethod method, AbcInstance instance) { return(BuildCtorImpl(method, instance) ?? BuildGetterImpl(method, instance) ?? BuildSetterImpl(method, instance) ?? BuildAddressImpl(method, instance)); }
private void LinkFields(IType type, AbcInstance instance) { foreach (var field in type.Fields) { LinkField(field, instance); } }
void ResolveXmlDeps(SwfMovie lib) { CacheScripts(lib); var abcFiles = lib.GetAbcFiles(); foreach (var abc in abcFiles) { AbcInstance defInstance = abc.Def; if (defInstance == null) { continue; } var scriptElem = abc.SwcElement; //if (_linker != null) // _linker.LinkType(defInstance); var depElems = GetElements(scriptElem, "dep"); foreach (var depElem in depElems) { string depID = depElem.GetAttribute("id"); string type = depElem.GetAttribute("type"); if (type == "n") { ResolveNamespace(defInstance, depID); } else { ResolveDefLink(defInstance, depID); } } } }
private bool IsOverrideGetTypeId(IType type, AbcInstance instance) { if (type.Is(SystemTypeCode.Exception)) { return(false); } var bt = type.BaseType; var st = instance.BaseInstance; while (bt != null && st != null) { if (st.IsObject) { return(false); } if (st.IsError) { return(false); } var m = DefineGetTypeIdMethod(bt, st); if (m != null) { return(true); } bt = bt.BaseType; st = st.BaseInstance; } return(false); }
private static void ResolveEmbed(SwfMovie lib, AbcInstance instance, AbcTrait trait) { if (instance.IsInterface) { return; } var superName = instance.BaseTypeName.FullName; if (!superName.EndsWith("Asset") || IsAssetClass(instance)) { return; } string className = instance.FullName; var asset = lib.FindAsset(className); if (asset == null) { CompilerReport.Add(Warnings.UnableFindSwfAsset, className); return; } Embed.Apply(trait, asset, lib); }
public AbcMethod Define_Assembly_InitType(IMethod method, AbcInstance instance) { _emitReflection = true; var m = instance.DefineMethod(_generator.MethodBuilder.SigOf(method), null); _generator.AddLateMethod( m, code => { //args: this, type, typeId const int argType = 1; const int argId = 2; code.LoadThis(); code.PushGlobalPackage(); code.PushString(Const.InitTypePrefix); code.GetLocal(argId); code.Add(InstructionCode.Add); code.GetRuntimeProperty(); code.CoerceFunction(); code.LoadThis(); code.GetLocal(argType); code.Add(InstructionCode.Call, 1); code.Pop(); code.ReturnVoid(); }); return(m); }
private SwfAsset AddSymbol(ISwfCharacter obj, AbcInstance instance) { if (obj == null) { throw new ArgumentNullException("obj"); } if (instance == null) { throw new ArgumentNullException("instance"); } var tag = obj as SwfTag; if (tag == null) { throw new ArgumentException("Character is not swf tag"); } if (!Swf.Tags.Contains(tag)) { Swf.Tags.Add(tag); } string name = instance.FullName; var asset = new SwfAsset(obj, name) { IsSymbol = true, }; _symbols.Add(asset); return(asset); }
private void FinishType(AbcInstance instance) { //TODO: Comment when copying of value types will be implemented using Reflection CopyImpl.Copy(instance); BuildCompiledMethods(instance); }
private List <AbcInstance> GetBaseTypesWithCctors(AbcInstance instance) { var list = new List <AbcInstance>(); var super = instance.BaseInstance; while (super != null) { if (super.IsObject) { break; } if (super.IsError) { break; } var ctor = _generator.StaticCtors.DefineStaticCtor(super); if (ctor != null) { list.Add(super); } super = super.BaseInstance; } list.Reverse(); return(list); }
private static void DefineDebugCollectionView(AbcGenerator generator, AbcInstance instance) { var name = generator.Abc.DefineName(QName.Global(DebugPropertyPrefix + "collection$view")); if (instance.FindSuperTrait(name, AbcTraitKind.Getter) != null) { return; } if (IsDictionary(generator, instance.Type)) { instance.DefineMethod( Sig.get(DebugPropertyPrefix + "dictionary$marker", AvmTypeCode.Boolean), code => { code.PushNativeBool(true); code.ReturnValue(); }); } instance.DefineMethod( Sig.get(name, AvmTypeCode.Array), code => { var m = generator.Corlib.GetMethod(CompilerMethodId.ToArray); code.Getlex(m); code.LoadThis(); code.Call(m); code.ReturnValue(); }); }
private void DefineFlexAppInitializer(AbcInstance instance) { Debug.Assert(instance.Initializer == null); instance.Initializer = Abc.DefineMethod( Sig.@global(null), code => { code.PushThisScope(); code.ConstructSuper(); code.Trace("PFC: calling App.initializer"); CtorAfterSuperCall(code); if (!IsFlex4) { var ctor = instance.FindParameterlessConstructor(); if (ctor != null) { var ctorMethod = _generator.MethodBuilder.BuildAbcMethod(ctor); AddEventListener(code, ctorMethod, FlexAppEvents.Initialize); } } code.ReturnVoid(); }); }
private void CompleteMethod(AbcInstance instance, IMethod method, AbcMethod abcMethod) { BuildBody(abcMethod); BuildImplementedMethods(method, instance, abcMethod); BuildOverrideMethods(method, abcMethod); ImplementProtoMethods(method, abcMethod); }
private void CallInitStyles(AbcCode code, AbcInstance instance) { code.Trace("PFC: calling App.initStyles"); var initStyles = DefineInitFlexAppStyles(instance); code.LoadThis(); code.Call(initStyles); }