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 static void Apply(AbcTrait trait, SwfAsset asset, SwfMovie lib) { if (trait.Embed != null) { return; } var klass = trait.Class; if (klass == null) { throw new InvalidOperationException("Embed can be applied to class trait only"); } var instance = klass.Instance; var embed = new Embed { Asset = asset, Movie = lib, Instance = instance }; trait.Embed = embed; trait.AssetInstance = instance; }
void GetSigRefs(AbcTrait trait) { switch (trait.Kind) { case AbcTraitKind.Class: throw new InvalidOperationException(); case AbcTraitKind.Const: case AbcTraitKind.Slot: AddSigRef(trait.SlotType); break; case AbcTraitKind.Function: case AbcTraitKind.Getter: case AbcTraitKind.Method: case AbcTraitKind.Setter: { var m = trait.Method; AddSigRef(m.ReturnType); foreach (var p in m.Parameters) { AddSigRef(p.Type); } } break; } }
private AbcMultiname GetAssetInstanceName(AbcTrait trait) { var owner = trait.Instance; string name = owner.NameString + "_" + trait.Name.NameString; return(Abc.DefineQName(owner.Name.Namespace, name)); }
private static void LinkField(IField field, AbcTrait trait) { if (trait == null) { throw new InvalidOperationException("Unable to link field " + field); } field.Data = trait; }
private IEnumerable <IInstruction> GetSlot(AbcTrait t) { var code = new AbcCode(_abc); GetSlot(code, t); _body.Flags |= AbcBodyFlags.HasSlotPointers; return(code); }
private AbcInstance BuildByteArrayAsset(AbcTrait trait) { var qname = _generator.IsFlexApplication ? QName.Package("mx.core", "ByteArrayAsset") : QName.Package("flash.utils", "ByteArray"); return(BuildAssetInstance(trait, Abc.DefineName(qname))); }
private IEnumerable <IInstruction> SetSlot(AbcTrait t) { var code = new AbcCode(_abc); GetActivation(code); code.Swap(); code.SetSlot(t); return(code); }
public AbcInstance SlotPtr(AbcTrait slot) { if (slot == null) { throw new ArgumentNullException("slot"); } return(_slotPtrs.Define(slot)); }
private AbcTrait CreateSlotPtr(AbcTrait slot) { PointerKind kind; var instance = DefineSlotPtrClass(slot, out kind); var t = CreateSlot(instance.Name, slot.NameString + "$ptr"); t.PtrSlot = slot; t.PtrKind = kind; return(t); }
private AbcInstance BuildAssetInstance(AbcTrait trait, AbcMultiname superName) { var name = GetAssetInstanceName(trait); //TODO: Check existance of instance var instance = BuildAssetInstance(name, superName); instance.Embed = trait.Embed; trait.AssetInstance = instance; return(instance); }
public AbcInstance Define(AbcTrait slot) { if (slot == null) { throw new ArgumentNullException("slot"); } //NOTE: VerifyError: Error #1026: Slot 1 exceeds slotCount=0 of Object //therefore we can not use Get/Set slots by slot_id. string name = "slot_ptr$" + slot.NameString; AbcInstance instance; if (_cache.TryGetValue(name, out instance)) { return(instance); } var abc = _generator.Abc; var instanceName = abc.DefineName(QName.PfxPackage(name)); instance = abc.DefineEmptyInstance(instanceName, false); _cache[name] = instance; var obj = instance.CreatePrivateSlot("_obj", AvmTypeCode.Object); instance.Initializer = abc.DefineTraitsInitializer(obj); instance.DefineMethod( Sig.ptr_get, code => { code.LoadThis(); code.GetProperty(obj); code.GetProperty(slot); code.ReturnValue(); }); instance.DefineMethod( Sig.ptr_set, code => { code.LoadThis(); code.GetProperty(obj); code.GetLocal(1); //value code.SetProperty(slot); code.ReturnVoid(); }); return(instance); }
private AbcInstance DefineSlotPtrClass(AbcTrait slot, out PointerKind kind) { if (AbcGenConfig.UseActivationTraits && AbcGenConfig.UseFuncPointers) { kind = PointerKind.FuncPtr; return(_generator.Pointers.FuncPtr.Instance); } //kind = PointerKind.SlotPtr; //return _generator.DefineSlotPtr(slot); kind = PointerKind.PropertyPtr; return(_generator.Pointers.PropertyPtr(slot.Name)); }
static string GetScriptName(AbcTrait trait) { var mn = trait.Name; string ns = mn.NamespaceString; string name = mn.NameString; if (string.IsNullOrEmpty(ns)) { return(name); } ns = ns.Replace('.', '/'); return(ns + "/" + name); }
public static void Resolve(AbcTrait trait, AbcMetaEntry e, SwfMovie lib) { if (trait.Embed != null) { return; } var klass = trait.Class; if (klass == null) { throw new InvalidOperationException("Embed can be applied to class trait only"); } string symbol = e[Attrs.Symbol]; string exportSymbol = e[Attrs.ExportSymbol]; string source = e[Attrs.Source]; var asset = lib.FindAsset(symbol); if (asset == null) { asset = lib.FindAsset(exportSymbol); if (asset == null) { throw Errors.Linker.UnableToFindSymbol.CreateException(symbol); } asset.IsExported = true; } var instance = klass.Instance; var embed = new Embed { Symbol = symbol, Asset = asset, Movie = lib, Source = source, ExportSymbol = exportSymbol, Instance = instance }; trait.Embed = embed; trait.AssetInstance = instance; }
private static void ListTrait(TextWriter writer, AbcTrait trait) { var k = trait.Kind; switch (k) { case AbcTraitKind.Slot: case AbcTraitKind.Const: { BeginTrait(writer, trait); WriteTypeName(writer, trait.SlotType); writer.Write(" "); WriteTraitName(writer, trait.Name); writer.WriteLine(";"); } break; case AbcTraitKind.Method: case AbcTraitKind.Getter: case AbcTraitKind.Setter: { var method = trait.Method; BeginTrait(writer, trait); WriteTypeName(writer, method.ReturnType); writer.Write(" "); if (k == AbcTraitKind.Getter) { writer.Write("get "); } else if (k == AbcTraitKind.Setter) { writer.Write("set "); } WriteTraitName(writer, trait.Name); WriteParams(writer, method); writer.WriteLine(";"); } break; case AbcTraitKind.Function: break; } }
public void Build(IField field, AbcTrait trait) { var attr = field.FindAttribute(Attrs.Embed); if (attr == null) { return; } _generator.CheckEmbedAsset(field); var embed = Embed.FromCustomAttribute(attr); trait.Embed = embed; string type = embed.MimeType; if (MimeTypes.IsBitmap(type)) { var instance = BuildBitmapAsset(trait); _generator.SwfCompiler.Assets.DefineBitmapAsset(embed.Source, instance); return; } if (MimeTypes.IsJpeg(type)) { var instance = BuildBitmapAsset(trait); _generator.SwfCompiler.Assets.DefineJpegAsset(embed.Source, instance); return; } if (string.Equals(type, MimeTypes.Application.OctetStream, StringComparison.OrdinalIgnoreCase)) { var instance = BuildByteArrayAsset(trait); _generator.SwfCompiler.Assets.DefineByteArrayAsset(embed.Source, instance); return; } //TODO: Support other mime-types throw Errors.RBC.NotSupportedMimeType.CreateException(embed.Source, embed.MimeType); }
private static void BeginTrait(TextWriter writer, AbcTrait trait) { var k = trait.Kind; writer.Write("\t"); //switch (k) //{ // case AbcTraitKind.Const: // case AbcTraitKind.Slot: // { // SlotTrait slot = (SlotTrait)trait.Data; // writer.Write(slot.SlotID); // writer.Write(" "); // } // break; // case AbcTraitKind.Method: // case AbcTraitKind.Getter: // case AbcTraitKind.Setter: // { // MethodTrait mt = ((MethodTrait)trait.Data); // writer.Write(mt.DispID); // writer.Write(" "); // } // break; //} writer.Write(trait.Visibility.ToString().ToLower()); writer.Write(" "); if (k == AbcTraitKind.Const) { writer.Write("const "); } else if (trait.IsStatic) { writer.Write("static "); } }
private void ProcessMeta(SwfMovie lib, AbcTrait trait, AbcMetaEntry e) { string name = e.NameString; if (name == MetadataTags.Embed) { Embed.Resolve(trait, e, lib); return; } if (name == MetadataTags.Mixin) { var klass = trait.Class; if (klass == null) { throw new InvalidOperationException("Mixin can be applied to class trait only"); } var instance = klass.Instance; RegisterMixin(instance); } }
private void GetSlot(AbcCode code, AbcTrait t) { GetActivation(code); code.GetSlot(t); }
private AbcMethod BuildCtorImpl(IMethod method, AbcInstance instance) { if (!method.IsConstructor) { return(null); } if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } var ctor = new AbcMethod { ReturnType = Abc.BuiltinTypes.Void }; _generator.MethodBuilder.BuildParameters(ctor, method); string name1 = "arrctor_" + type.GetSigName(); var name = Abc.DefineName(QName.Global(name1)); var trait = AbcTrait.CreateMethod(ctor, name); instance.Traits.Add(trait); var body = new AbcMethodBody(ctor); Abc.AddMethod(ctor); var code = new AbcCode(Abc); code.PushThisScope(); code.ConstructSuper(); //check arguments int n = method.Parameters.Count; for (int i = 0; i < n; ++i) { code.GetLocal(i + 1); code.PushInt(0); var br = code.If(BranchOperator.GreaterThanOrEqual); var exceptionType = _generator.Corlib.GetType(CorlibTypeId.ArgumentOutOfRangeException); code.ThrowException(exceptionType); br.BranchTarget = code.Label(); } //m_rank = n code.LoadThis(); code.PushInt(n); code.SetProperty(Const.Array.Rank); int varSize = n + 1; for (int i = 0; i < n; ++i) { code.GetLocal(i + 1); } for (int i = 1; i < n; ++i) { code.Add(InstructionCode.Multiply_i); } code.SetLocal(varSize); //init m_value code.LoadThis(); code.CreateArrayVarSize(varSize); code.SetProperty(Const.Array.Value); //init m_lengths code.LoadThis(); for (int i = 0; i < n; ++i) { code.GetLocal(i + 1); } code.Add(InstructionCode.Newarray, n); code.SetProperty(Const.Array.Lengths); int varDimArr = varSize + 1; //init m_dims code.CreateArray(n - 1); code.SetLocal(varDimArr); //1, n, n * (n-1), ..., n * (n-1) * ... * n0 for (int i = n - 2; i >= 0; --i) { int leni = i + 2; code.GetLocal(varDimArr); code.PushInt(i); if (i != n - 2) { code.GetLocal(varDimArr); code.PushInt(i + 1); code.GetNativeArrayItem(); code.CoerceInt32(); //prev code.GetLocal(leni); code.Add(InstructionCode.Multiply_i); //prev * leni } else { code.GetLocal(leni); } code.SetNativeArrayItem(); } code.LoadThis(); code.GetLocal(varDimArr); code.SetProperty(Const.Array.Dims); var elemType = type.GetElementType(); InitFields(code, type, elemType, 0); if (InternalTypeExtensions.IsInitArray(elemType)) { code.InitArray(elemType, () => { code.LoadThis(); code.GetProperty(Const.Array.Value); }, varSize); } code.ReturnVoid(); body.Finish(code); return(ctor); }
public static XElement ToXml(this AbcTrait trait) { var res = new XElement("trait", new XAttribute("name", trait.Name.ToXml()), new XAttribute("kind", trait.Kind)); if (trait.Final) { res.Add(new XAttribute("final", CommonFormatter.Format(trait.Final))); } if (trait.Override) { res.Add(new XAttribute("override", CommonFormatter.Format(trait.Override))); } switch (trait.Kind) { case AsTraitKind.Slot: var slot = (AbcSlotTrait)trait; res.Add(new XAttribute("slotId", slot.SlotId)); res.Add(new XAttribute("typeName", slot.TypeName.ToXml())); res.Add(new XAttribute("value", slot.Value.ToXml())); break; case AsTraitKind.Const: var con = (AbcConstTrait)trait; res.Add(new XAttribute("slotId", con.SlotId)); res.Add(new XAttribute("typeName", con.TypeName.ToXml())); res.Add(new XAttribute("value", con.Value.ToXml())); break; case AsTraitKind.Class: var cl = (AbcClassTrait)trait; res.Add(new XAttribute("slotId", cl.SlotId)); //todo: class ref break; case AsTraitKind.Function: var func = (AbcFunctionTrait)trait; res.Add(new XAttribute("slotId", func.SlotId)); //todo: method ref break; case AsTraitKind.Method: var met = (AbcMethodTrait)trait; res.Add(new XAttribute("dispId", met.DispId)); //todo: method ref break; case AsTraitKind.Getter: var getter = (AbcGetterTrait)trait; res.Add(new XAttribute("dispId", getter.DispId)); //todo: method ref break; case AsTraitKind.Setter: var setter = (AbcSetterTrait)trait; res.Add(new XAttribute("dispId", setter.DispId)); //todo: method ref break; default: throw new Exception("unsupported trait kind " + trait.Kind); } if (trait.Metadata.Count > 0) { res.Add(trait.Metadata.ToXml()); } return(res); }
public void Build(IField field) { if (field == null) { throw new ArgumentNullException("field"); } if (MustExclude(field)) { return; } if (Abc.IsDefined(field)) { return; } var declType = field.DeclaringType; var tag = _generator.TypeBuilder.Build(declType); var instance = tag as AbcInstance; if (instance == null) { throw new InvalidOperationException(); } if (instance.IsForeign) { return; } if (Abc.IsDefined(field)) { return; } var type = _generator.TypeBuilder.BuildMemberType(field.Type); if (Abc.IsDefined(field)) { return; } #if DEBUG DebugService.LogInfo("ABC DefineField started for field {0}.{1}", field.DeclaringType.FullName, field.Name); #endif var name = DefineName(field); bool isStatic = field.IsStatic; AbcTrait trait = null; //Try to find trait, may be it has already been defined if (field.Data != null) { var kind = field.IsConstant ? AbcTraitKind.Const : AbcTraitKind.Slot; trait = isStatic ? instance.Class.Traits.Find(name, kind) : instance.Traits.Find(name, kind); } if (trait == null) { trait = AbcTrait.CreateSlot(type, name); _generator.SetData(field, trait); instance.AddTrait(trait, isStatic); if (IsImportableConstant(field)) { trait.Kind = AbcTraitKind.Const; trait.HasValue = true; trait.SlotValue = Abc.ImportValue(field.Value); } _generator.EmbeddedAssets.Build(field, trait); } else { _generator.SetData(field, trait); } trait.Type = field.Type; trait.Field = field; #if DEBUG DebugService.LogInfo("ABC DefineField succeeded for field {0}", field.FullName); #endif }
private AbcInstance BuildBitmapAsset(AbcTrait trait) { return(BuildAssetInstance(trait, GetBitmapAssetSuperName())); }