示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
 public void DefineScriptInit(AbcScript script)
 {
     script.Initializer = DefineMethod(
         Sig.@void(),
         code =>
     {
         code.PushThisScope();
         code.InitClassProperties(script);
         code.ReturnVoid();
     }
         );
 }
示例#4
0
        /// <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();
            }
                       ));
        }
示例#5
0
        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);
        }
示例#6
0
 public AbcMethod DefineEmptyMethod()
 {
     return(DefineMethod(
                Sig.global(null),
                code => code.ReturnVoid()));
 }
示例#7
0
 internal AbcMethod DefineMethod(Sig sig, AbcCoder coder)
 {
     return(DefineMethod(sig, coder, null));
 }
示例#8
0
        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);
        }