예제 #1
0
        void DefinePrototype(AvmTypeCode type, AbcMethod sig)
        {
            var srcmethod = sig.Method;

            if (srcmethod == null)
            {
                return;
            }

            string key = GetKey(type, srcmethod.Name);
            var    val = _prototypes[key] as object[];

            if (val == null)
            {
                return;
            }

            var m = val[1] as AbcMethod;

            if (m != null)
            {
                return;
            }

            var coder = val[0] as AbcCoder;

            m = Abc.DefineMethod(Sig.@from(sig), coder);

            _generator.NewApi.SetProtoFunction(type, sig.TraitName, m);

            val[0] = m;
        }
예제 #2
0
        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);
            });
        }
예제 #3
0
 private static void Build(AbcInstance instance, IMethod method)
 {
     instance.DefineMethod(
         Sig.@from(method.AbcMethod()),
         code =>
     {
         var impl = Impls[method.Name];
         impl(method, code);
     });
 }
예제 #4
0
        private void GetEnumeratorImpl(IType elemType)
        {
            var iface = _generator.Corlib.MakeIEnumerable(elemType);

            _generator.TypeBuilder.BuildInstance(iface);
            var ifaceMethod    = iface.Methods[0];
            var ifaceAbcMethod = _generator.MethodBuilder.BuildAbcMethod(ifaceMethod);

            Instance.DefineMethod(
                Sig.@from(ifaceAbcMethod),
                code =>
            {
                var implType = BuildArrayEnumerator(elemType);
                var ctor     = implType.FindConstructor(1);
                code.NewObject(ctor, () => code.LoadThis());
                code.ReturnValue();
            });
        }
예제 #5
0
        //Called when GetTypeId method is used.
        public AbcMethod DefineGetTypeIdMethod(IType type, AbcInstance instance)
        {
            if (type == null)
            {
                return(null);
            }
            if (instance == null)
            {
                return(null);
            }
            if (instance.IsNative)
            {
                return(null);
            }
            if (instance.IsInterface)
            {
                return(null);
            }
            if (instance.IsForeign)
            {
                return(null);
            }

            var abc = instance.Abc;

            if (IsSwf)
            {
                if (!((IEnumerable <AbcFile>)SwfCompiler.AbcFrames).Contains(abc))
                {
                    return(null);
                }
            }
            else
            {
                if (abc != Abc)
                {
                    return(null);
                }
            }

            string name1 = Const.GetTypeId;
            var    name  = abc.DefineName(QName.Global(name1));
            var    trait = instance.Traits.FindMethod(name);

            if (trait != null)
            {
                return(trait.Method);
            }

            var method = instance.DefineMethod(
                Sig.@virtual(name, AvmTypeCode.Int32),
                code => code.ReturnTypeId(type));

            method.Trait.IsOverride = IsOverrideGetTypeId(type, instance);

            //File.AppendAllText("c:\\GetTypeId.txt", type.FullName + "\n");

            if (type.Is(SystemTypeCode.Exception))
            {
                //DefinePrototype_GetType(instance, type);

                var getTypeId = _generator.Corlib.GetMethod(ObjectMethodId.GetTypeId);
                instance.DefineMethod(Sig.@from(getTypeId).@override(false), code => code.ReturnTypeId(type));

                var prototype = _generator.Corlib.GetMethod(ObjectMethodId.GetType);
                instance.DefineMethod(Sig.@from(prototype).@override(false), code =>
                {
                    code.CallAssemblyGetType(
                        () =>
                    {
                        code.LoadThis();
                        code.Call(getTypeId);
                    }
                        );
                    code.ReturnValue();
                });
            }

            return(method);
        }