internal AbcMethod DefineMethod(Sig sig, AbcCoder coder) { var method = new AbcMethod { ReturnType = sig.ReturnType != null ? DefineTypeNameSafe(sig.ReturnType) : null }; if (sig.Args != null) { AddParameters(method.Parameters, sig.Args); } var body = new AbcMethodBody(method); AddMethod(method); if (coder != null) { var code = new AbcCode(this); coder(code); body.Finish(code); } return(method); }
public AbcInstance DefineEmptyInstance(object name, bool emptyCtor) { var instance = new AbcInstance(true) { Name = DefineName(name), BaseTypeName = BuiltinTypes.Object, Flags = AbcClassFlags.Final | AbcClassFlags.Sealed }; if (emptyCtor) { instance.Initializer = DefineMethod( Sig.@void(), code => { code.ConstructSuper(); code.ReturnVoid(); }); } instance.Class.Initializer = DefineEmptyMethod(); AddInstance(instance); return(instance); }
public void DefineScriptInit(AbcScript script) { script.Initializer = DefineMethod( Sig.@void(), code => { code.PushThisScope(); code.InitClassProperties(script); code.ReturnVoid(); } ); }
/// <summary> /// Defines instance initializer which init given traits. /// </summary> /// <param name="args"></param> /// <returns></returns> public AbcMethod DefineTraitsInitializer(params object[] args) { var pairs = args .Pairwise(x => x is string? 1 : 0) .Select(x => { var t = x.First as AbcTrait; if (t == null) { throw new InvalidOperationException(); } if (!t.IsSlot) { throw new InvalidOperationException(); } return(new KeyValuePair <AbcTrait, string>(t, x.Second as string)); }) .ToList(); var traits = pairs.Select(x => x.Key).ToList(); return(DefineMethod( Sig.global(AvmTypeCode.Void, args), code => { code.PushThisScope(); code.ConstructSuper(); for (int i = 0; i < traits.Count; ++i) { code.LoadThis(); code.GetLocal(i + 1); code.SetProperty(traits[i]); } code.ReturnVoid(); } )); }
public void ImportResourceBundle(string locale, string name, ResourceBundleContext context) { if (context == null) { context = new ResourceBundleContext(); } context.Locale = locale; ResourceBundles.CopyFlexLocale(locale); string key = locale + "$" + name; if (ContainsResourceBundle(key)) { return; } var rb = ResourceBundles.Get(locale, name); //NOTE: null in case of Dynamic Resource Modules!!! if (rb == null) { return; } var superType = ResourceBundleSuper; var instance = new AbcInstance(true) { ResourceBundleName = name, Locale = locale }; _rbcache[key] = instance; //NOTE: naming is strongly determined in Flex Resource Manager. string fullname = locale + '$' + name + "_properties"; instance.Name = DefineName(QName.Global(fullname)); instance.Flags = AbcClassFlags.Sealed | AbcClassFlags.ProtectedNamespace; instance.ProtectedNamespace = DefineProtectedNamespace(fullname); instance.BaseInstance = superType; instance.BaseTypeName = superType.Name; AddInstance(instance); instance.Initializer = DefineMethod( Sig.@void(), code => { code.PushThisScope(); code.LoadThis(); code.PushString(locale); code.PushString(name); code.ConstructSuper(2); code.ReturnVoid(); }); instance.Class.Initializer = DefineEmptyMethod(); var mn = DefineQName(instance.ProtectedNamespace, "getContent"); instance.DefineMethod( Sig.@override(mn, AvmTypeCode.Object), code => { int n = 0; var lines = rb.Content; for (int i = 0; i < lines.Length; ++i) { string line = lines[i]; context.Line = i + 1; context.ResourceBundle = rb; if (PushKeyValue(line, code, context)) { ++n; } } code.Add(InstructionCode.Newobject, n); code.ReturnValue(); } ); DefineScript(instance); }
public AbcMethod DefineEmptyMethod() { return(DefineMethod( Sig.global(null), code => code.ReturnVoid())); }
internal AbcMethod DefineMethod(Sig sig, AbcCoder coder) { return(DefineMethod(sig, coder, null)); }
internal AbcMethod DefineMethod(Sig sig, AbcCoder coder, Action <AbcMethod> complete) { if (sig == null) { throw new ArgumentNullException("sig"); } if (!sig.IsInitilizer && sig.Name == null) { throw new InvalidOperationException(); } var klass = Class; if (klass == null) { throw new InvalidOperationException(string.Format("Class is not defined yet for Instance {0}", FullName)); } AbcMultiname traitName = null; AbcTrait trait; bool isStatic = (sig.Semantics & MethodSemantics.Static) != 0; var traits = isStatic ? klass.Traits : Traits; if (sig.IsInitilizer) { if (Initializer != null) { throw new InvalidOperationException(); } } else { traitName = Abc.DefineName(sig.Name); trait = traits.Find(traitName, sig.Kind); if (trait != null) { return(trait.Method); } } var method = new AbcMethod { Method = sig.Source }; var generator = Abc.Generator; if (sig.Source != null) { generator.SetData(sig.Source, method); } AbcMethodBody body = null; if (sig.IsAbstract) { if (coder != null) { throw new InvalidOperationException(); } } else { body = new AbcMethodBody(method); } Abc.AddMethod(method); if (sig.IsInitilizer) { Initializer = method; } else { //for non initializer method we must define trait and return type method.ReturnType = BuildReturnType(sig.ReturnType, method); trait = AbcTrait.CreateMethod(method, traitName); trait.Kind = sig.Kind; if (!isStatic) { trait.IsVirtual = (sig.Semantics & MethodSemantics.Virtual) != 0; trait.IsOverride = (sig.Semantics & MethodSemantics.Override) != 0; } traits.Add(trait); } if (sig.Args != null) { if (sig.Args.Length == 1 && sig.Args[0] is IMethod) { var m = (IMethod)sig.Args[0]; if (generator == null) { throw new InvalidOperationException(); } generator.MethodBuilder.BuildParameters(method, m); } else { Abc.AddParameters(method.Parameters, sig.Args); } } if (body != null && coder != null) { var code = new AbcCode(Abc); coder(code); body.Finish(code); } if (complete != null) { complete(method); } return(method); }