Exemple #1
0
        private AbcMethod BuildUnary(IMethod op)
        {
            if (op == null)
            {
                throw new ArgumentNullException("op");
            }

            var abcOp = _generator.MethodBuilder.BuildAbcMethod(op);

            var instance = _generator.TypeBuilder.BuildInstance(op.DeclaringType);

            string name     = "this_" + abcOp.TraitName.NameString;
            var    thisName = Abc.DefineName(QName.Global(name));
            var    retType  = _generator.TypeBuilder.BuildReturnType(op.Type);

            return(instance.DefineMethod(
                       Sig.@this(thisName, retType),
                       code =>
            {
                code.Getlex(instance);
                code.GetLocal(0);
                code.Call(abcOp);
                code.Coerce(op.Type, true);
                code.ReturnValue();
            }));
        }
Exemple #2
0
        private AbcMethod BuildAddressImpl(IMethod method, AbcInstance instance)
        {
            if (method.IsStatic)
            {
                return(null);
            }
            var type = method.DeclaringType;

            if (!type.IsArray)
            {
                return(null);
            }
            if (method.Name != CLRNames.Array.Address)
            {
                return(null);
            }

            var elemPtr = _generator.Pointers.ElemPtr.Instance;

            string name = "GetAddr_" + method.GetParametersSignature(Runtime.Avm);

            return(instance.DefineMethod(
                       Sig.@this(name, elemPtr.Name, method),
                       code =>
            {
                code.Getlex(elemPtr);
                code.LoadThis();                                 //arr
                ToFlatIndex(code, method.Parameters.Count, true);
                code.Construct(2);
                code.ReturnValue();
            }));
        }
Exemple #3
0
        public AbcMethod Build(BinaryOperator op, IType left, IType right)
        {
            var method = Find(op, left, right);

            if (method == null)
            {
                throw new InvalidOperationException();
            }

            var abcOp = _generator.MethodBuilder.BuildAbcMethod(method);

            var instance = _generator.TypeBuilder.BuildInstance(method.DeclaringType);

            Debug.Assert(instance.Abc == Abc);

            string name     = "this_" + abcOp.TraitName.NameString;
            var    thisName = Abc.DefineName(QName.Global(name));
            var    retType  = _generator.TypeBuilder.BuildReturnType(method.Type);

            return(instance.DefineMethod(
                       Sig.@this(thisName, retType, right, "right"),
                       code =>
            {
                code.Getlex(instance);
                code.GetLocal(0);                         //left
                code.GetLocal(1);                         //right
                code.Call(abcOp);
                code.Coerce(retType);
                code.ReturnValue();
            }));
        }
Exemple #4
0
        private AbcMethod BuildSetterImpl(IMethod method, AbcInstance instance)
        {
            if (method.IsStatic)
            {
                return(null);
            }
            var type = method.DeclaringType;

            if (!type.IsArray)
            {
                return(null);
            }
            if (method.Name != CLRNames.Array.Setter)
            {
                return(null);
            }

            var name = _generator.MethodBuilder.DefineQName(method);

            return(instance.DefineMethod(
                       Sig.@this(name, method.Type, method),
                       code =>
            {
                int n = method.Parameters.Count;
                code.LoadThis();
                ToFlatIndex(code, n, false);
                code.GetLocal(n);                                 //value
                code.SetArrayElem(false);
                code.ReturnVoid();
            }));
        }
Exemple #5
0
        private AbcMethod BuildGetterImpl(IMethod method, AbcInstance instance)
        {
            if (method.IsStatic)
            {
                return(null);
            }
            var type = method.DeclaringType;

            if (!type.IsArray)
            {
                return(null);
            }
            if (method.Name != CLRNames.Array.Getter)
            {
                return(null);
            }

            //string name = "Get" + NameUtil.GetParamsString(method);
            var name = _generator.MethodBuilder.DefineQName(method);

            return(instance.DefineMethod(
                       Sig.@this(name, method.Type, method),
                       code =>
            {
                code.LoadThis();
                ToFlatIndex(code, method.Parameters.Count, true);
                code.GetArrayElem(method.Type, false);
                code.ReturnValue();
            }));
        }
Exemple #6
0
        void DefineInitTypeMethod(IType type, int typeId)
        {
            Debug.Assert(typeId >= 0);

            var instance = _generator.Corlib.Assembly.Instance;

            instance.DefineMethod(
                Sig.@this(QName.Global(Const.InitTypePrefix + typeId),
                          AvmTypeCode.Void,
                          SystemTypes.Type, "type"),
                code =>
            {
                InitTypeInfo(code, type, typeId);
                code.ReturnVoid();
            });
        }
Exemple #7
0
        public AbcMethod GetElemPtr()
        {
            var instance = _generator.Corlib.Array.Instance;

            var name = _generator.Abc.DefineName(QName.PfxPublic("GetElemPtr"));

            return(instance.DefineMethod(
                       Sig.@this(name, AvmTypeCode.Object, AvmTypeCode.Int32, "index"),
                       code =>
            {
                var ptr = ElemPtr.Instance;
                code.Getlex(ptr);
                code.LoadThis();
                code.GetLocal(1);                                 //index
                code.Construct(2);
                code.ReturnValue();
            }));
        }
Exemple #8
0
        /// <summary>
        /// Signature: void Instance.__copy_from__(Instance value)
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static AbcMethod CopyFrom(AbcInstance instance)
        {
            var type = instance.Type;

            if (!type.SupportsCopyMethods())
            {
                return(null);
            }

            var generator = instance.Generator;
            var name      = generator.Abc.DefineName(QName.PfxPublic("__copy_from__"));

            return(instance.DefineMethod(
                       Sig.@this(name, AvmTypeCode.Void, instance.Name, "value"),
                       code =>
            {
                code.CopySlots(instance, 1, 0);
                code.ReturnVoid();
            }));
        }
Exemple #9
0
        private AbcMethod DefineInitFlexAppStyles(AbcInstance instance)
        {
            var done = instance.DefineSlot("_init_styles_done", AvmTypeCode.Boolean);

            return(instance.DefineMethod(
                       Sig.@this("$init_flex_styles$", AvmTypeCode.Void),
                       code =>
            {
                code.LoadThis();
                code.GetProperty(done);

                var br = code.IfFalse();
                code.ReturnVoid();

                br.BranchTarget = code.Label();

                code.LoadThis();
                code.Add(InstructionCode.Pushtrue);
                code.SetProperty(done);

                //TODO: init app CSSStyleDeclaration
                //TODO: init app effects

                if (IsFlex4)
                {
                    code.LoadThis();
                    code.GetProperty("styleManager");
                    code.CallVoid("initProtoChainRoots", 0);
                }
                else
                {
                    var styleMgr = _generator.ImportType("mx.styles.StyleManager");
                    code.Getlex(styleMgr);
                    code.CallVoid(Abc.DefineName(QName.MxInternal("initProtoChainRoots")), 0);
                }

                code.ReturnVoid();
            }));
        }
Exemple #10
0
        private AbcMethod DefineBaseCall(IType receiverType, IMethod method)
        {
            var instance = DefineAbcInstance(receiverType);

            var    mname  = GetMethodName(method);
            string prefix = "$C" + instance.Index;

            prefix += GetBaseCallPrefix(method);

            var rname   = _abc.DefineQName(mname.Namespace, prefix + mname.NameString);
            var retType = DefineMemberType(method.Type);

            return(instance.DefineMethod(
                       Sig.@this(rname, retType, method),
                       code =>
            {
                code.LoadThis();
                code.LoadArguments(method);
                CallCore(code, method, mname, true);
                code.Return(method);
            }));
        }
Exemple #11
0
        /// <summary>
        /// Signature: Instance Instance.__copy__()
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static AbcMethod Copy(AbcInstance instance)
        {
            var type = instance.Type;

            if (type == null)
            {
                return(null);
            }
            if (!type.SupportsCopyMethods())
            {
                return(null);
            }

            var generator = instance.Generator;
            var name      = generator.Abc.DefineName(QName.PfxPublic("__copy__"));

            return(instance.DefineMethod(
                       Sig.@this(name, instance.Name),
                       code =>
            {
                //SUPER BUG:
                //For some times like System.Int64 DefineCopyMethod method can be called before DefineFields
                //so we should define type fields
                generator.TypeBuilder.DefineFields(type);

                const int obj = 1;
                code.CreateInstance(instance);

                code.SetLocal(obj);

                code.CopySlots(instance, 0, obj);

                code.GetLocal(obj);
                code.ReturnValue();
            }));
        }
Exemple #12
0
        void BuildSystemManagerInfo(AbcFile abc, AbcInstance instance)
        {
            var objType = abc.BuiltinTypes.Object;

            if (_cacheInfoObject)
            {
                var method = instance.DefineMethod(Sig.@this("$info$", objType), null);
                _compiler.AddLateMethod(method, BuildSystemManagerInfo);

                var infoField = instance.DefineSlot("__info", AvmTypeCode.Object);

                instance.DefineMethod(
                    Sig.@virtual("info", objType).@override(),
                    code =>
                {
                    code.LoadThis();
                    code.GetProperty(infoField);

                    var br = code.IfNotNull();
                    code.LoadThis();
                    code.LoadThis();
                    code.Call(method);
                    code.SetProperty(infoField);

                    br.BranchTarget = code.Label();
                    code.LoadThis();
                    code.GetProperty(infoField);
                    code.ReturnValue();
                });
            }
            else
            {
                var method = instance.DefineMethod(Sig.@virtual("info", objType).@override(), null);
                _compiler.AddLateMethod(method, BuildSystemManagerInfo);
            }
        }
Exemple #13
0
        internal AbcInstance DefineFlexInitMixin(AbcFile app)
        {
            var flexModuleFactoryInterface = FlexTypes.GetFlexModuleFactoryInterface(app);
            var childManagerInstance       = FlexTypes.GetChildManagerInstance(app);
            var flex4 = childManagerInstance != null;

            string name = "_FlexInit_" + _compiler.FlexAppPrefix;
            string ns   = _compiler.RootNamespace;

            var instance = new AbcInstance(true)
            {
                Name            = app.DefineName(QName.Package(ns, name)),
                BaseTypeName    = app.BuiltinTypes.Object,
                IsMixin         = true,
                IsFlexInitMixin = true,
                Initializer     = app.DefineMethod(
                    Sig.@this(null, AvmTypeCode.Void),
                    code =>
                {
                    code.ConstructSuper();
                    code.ReturnVoid();
                }),
                Class = { Initializer = app.DefineEmptyMethod() }
            };

            app.AddInstance(instance);

            instance.DefineMethod(
                Sig.@static("init", AvmTypeCode.Void, flexModuleFactoryInterface, "f"),
                code =>
            {
                code.PushThisScope();

                const int moduleFactoryArg = 1;
                const int styleManagerVar  = 2;

                if (flex4)
                {
                    CreateInstance(code, childManagerInstance, moduleFactoryArg);
                    code.Pop();

                    var styleManager2    = FlexTypes.GetStyleManager2Interface(app);
                    var styleManagerImpl = FlexTypes.GetStyleManagerImpl(app);
                    CreateInstance(code, styleManagerImpl, moduleFactoryArg);
                    code.Coerce(styleManager2);
                    code.SetLocal(styleManagerVar);
                }

                RegisterEffectTriggers(app, code);
                RegisterRemoteClasses(app, code);

                Action pushStyleManager;
                if (flex4)
                {
                    pushStyleManager = () => code.GetLocal(styleManagerVar);
                }
                else
                {
                    pushStyleManager = () => code.Getlex(FlexTypes.GetStyleManagerInstance(app));
                }

                RegisterInheritStyles(app, code, pushStyleManager, flex4);

                //NOTE: Uncomment to add forward refernce to Flex Application
                //var appInstance = app.generator.MainInstance;
                //code.Trace(string.Format("PFC: forward reference to FlexApp class {0}", appInstance.FullName));
                //code.Getlex(appInstance);
                //code.Pop();

                code.ReturnVoid();
            });

            return(instance);
        }
Exemple #14
0
        public AbcMethod GetElemInt64(IType elemType, bool item)
        {
            if (elemType == null)
            {
                throw new ArgumentNullException("elemType");
            }

            if (!elemType.IsInt64Based())
            {
                throw new ArgumentException("Invalid elem type");
            }

            if (elemType.IsEnum)
            {
                elemType = elemType.ValueType;
            }

            string name             = (item ? "get_item_" : "get_elem_") + elemType.GetSigName();
            var    elemTypeName     = BuildReturnType(elemType);
            var    oppositeType     = elemType.Is(SystemTypeCode.Int64) ? SystemTypes.UInt64 : SystemTypes.Int64;
            var    oppositeTypeName = BuildReturnType(oppositeType);

            return(Instance.DefineMethod(
                       Sig.@this(name, elemTypeName, AvmTypeCode.Int32, "index"),
                       code =>
            {
                const int index = 1;
                const int value = 2;

                code.LoadThis();
                code.GetLocal(index);
                code.Call(item ? ArrayMethodId.GetItem : ArrayMethodId.GetElem);
                code.CoerceObject();
                code.SetLocal(value);

                //check elemType
                code.GetLocal(value);
                code.As(elemTypeName);
                code.PushNull();
                var ifElemType = code.IfNotEquals();

                //check opposite type
                code.GetLocal(value);
                code.As(oppositeTypeName);
                code.PushNull();
                var ifOppositeType = code.IfNotEquals();

                code.ThrowInvalidCastException("not int64");

                //casting
                var labelCast = code.Label();
                ifOppositeType.BranchTarget = labelCast;
                //gotoCast.BranchTarget = labelCast;
                code.GetLocal(value);
                code.Cast(oppositeType, elemType);
                code.ReturnValue();

                var normalExit = code.Label();
                ifElemType.BranchTarget = normalExit;

                code.GetLocal(value);
                code.Coerce(elemTypeName);
                code.ReturnValue();
            }));
        }