private static bool DefineDebuggerDisplay(AbcGenerator generator, IType type, AbcInstance instance, ICustomAttribute attr) { if (attr.Arguments.Count != 1) { return(false); } var display = attr.Arguments[0].Value as string; if (string.IsNullOrEmpty(display)) { return(false); } if (!display.CheckFormatBraceBalance()) { CompilerReport.Add(Warnings.InvalidDebuggerDisplayString, display); return(false); } var name = generator.Abc.DefineName(QName.Global(DebugPropertyPrefix + "display$exp")); //TODO: Parse display string to build string var m = instance.DefineMethod( Sig.get(name, AvmTypeCode.String), code => { code.PushString(display); code.ReturnValue(); }); m.Trait.IsVirtual = !type.IsSealed; m.Trait.IsOverride = instance.FindSuperTrait(name, AbcTraitKind.Getter) != null; return(true); }
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(); }); }
public AbcMethod IsFlashPlayer() { var instance = _generator.Corlib.Environment.Instance; return(instance.DefineMethod( Sig.get("isFlash", Abc.BuiltinTypes.RealBoolean).@static(), code => { var isFlash = instance.DefineStaticSlot("__isFlash", AvmTypeCode.Boolean); var isFlashInitialized = instance.DefineStaticSlot("__isFlashInitialized", AvmTypeCode.Boolean); code.GetLocal(0); code.GetProperty(isFlashInitialized); var ifTrue = code.IfTrue(); code.GetLocal(0); code.GetLocal(0); var m = IsFlashPlayerInternal(); code.Call(m); code.SetProperty(isFlash); ifTrue.BranchTarget = code.Label(); code.GetLocal(0); code.GetProperty(isFlash); code.FixBool(); code.ReturnValue(); })); }
private static void DefineDebuggerDisplay(AbcGenerator generator, IType type, AbcInstance instance) { if (type.IsInterface) { return; } if (type.Is(SystemTypeCode.Object)) { return; } if (type.Is(SystemTypeCode.String)) { return; } if (type.Is(SystemTypeCode.Array)) { return; } //MSDN: DebuggerDisplay attribute takes precedence over the ToString() override var attr = type.FindAttribute(Attrs.DebuggerDisplay); if (attr != null) { if (DefineDebuggerDisplay(generator, type, instance, attr)) { return; } } //Use ToString var toString = type.Methods.Find(Const.Object.MethodToString, 0); if (toString != null) { var tostr = generator.MethodBuilder.BuildAbcMethod(toString); var name = generator.Abc.DefineName(QName.Global(DebugPropertyPrefix + "display")); var m = instance.DefineMethod( Sig.get(name, AvmTypeCode.String), code => { code.LoadThis(); // this might be redundant --olegz code.Call(tostr); code.ReturnValue(); }); // as soon the method will be overridden in descendants we have to mark it as virtual (case 147084) m.Trait.IsVirtual = !type.IsSealed; m.Trait.IsOverride = instance.FindSuperTrait(name, AbcTraitKind.Getter) != null; } }
private AbcMethod IsFlashPlayerInternal() { var instance = _generator.Corlib.Environment.Instance; return(instance.DefineMethod( Sig.get("isFlashInternal", Abc.BuiltinTypes.Boolean).@static(), code => { code.GetPlayerType(); code.PushString("AVMPlus"); code.Add(InstructionCode.Equals); code.Add(InstructionCode.Not); code.ReturnValue(); })); }
public static AbcInstance Define(AbcGenerator generator, IField field) { if (field == null) { throw new ArgumentNullException("field"); } if (!field.IsStatic) { throw new ArgumentException("field is not static"); } var abc = generator.Abc; var type = field.DeclaringType; string typeName = type.FullName.MakeFullName(field.Name); var name = abc.DefineName(QName.PfxPublic("sfld_ptr$" + typeName)); var instance = abc.Instances[name]; if (instance != null) { return(instance); } var fieldInstance = generator.TypeBuilder.BuildInstance(type); instance = abc.DefineEmptyInstance(name, true); instance.DefineMethod( Sig.ptr_get, code => { code.Getlex(fieldInstance); code.GetField(field); code.ReturnValue(); }); instance.DefineMethod( Sig.ptr_set, code => { code.Getlex(fieldInstance); code.GetLocal(1); //value code.SetField(field); code.ReturnVoid(); }); var ti = instance.CreatePrivateStaticSlot("_instance", instance); instance.DefineMethod( Sig.get(Const.Instance, instance.Name).@static(), code => { code.LoadThis(); code.GetProperty(ti); var br = code.IfNotNull(true); code.LoadThis(); code.LoadThis(); code.Construct(0); code.SetProperty(ti); br.BranchTarget = code.Label(); code.LoadThis(); code.GetProperty(ti); code.ReturnValue(); }); return(instance); }