Пример #1
0
        public static InlineCall Create(AbcFile abc, IMethod method, InlineMethodInfo info)
        {
            var code       = new AbcCode(abc);
            var targetType = info.TargetType != null?info.TargetType.Define(abc) : null;

            var name = info.Name.Define(abc);

            switch (info.Kind)
            {
            case InlineKind.Property:
                if (method.IsSetter())
                {
                    code.SetProperty(name);
                }
                else
                {
                    code.GetProperty(name);
                    code.Coerce(method.Type, true);
                }
                break;

            case InlineKind.Operator:
            {
                int n = method.Parameters.Count;
                if (n <= 1)
                {
                    throw new InvalidOperationException();
                }
                var op = info.Op;
                for (int i = 1; i < n; ++i)
                {
                    code.Add(op);
                }
                code.Coerce(method.Type, true);
            }
            break;

            default:
                if (method.IsVoid())
                {
                    code.CallVoid(name, method.Parameters.Count);
                }
                else
                {
                    code.Call(name, method.Parameters.Count);
                    code.Coerce(method.Type, true);
                }
                break;
            }

            return(new InlineCall(method, targetType, name, code));
        }
Пример #2
0
        public static void CopyArray(AbcCode code)
        {
            var prop = code.Abc.DefineName(QName.Global("concat"));

            code.Call(prop, 0);
            code.Coerce(AvmTypeCode.Array);
        }
Пример #3
0
        public static void Getter(IMethod method, AbcCode code)
        {
            var prop = method.Association as IProperty;

            if (prop == null)
            {
                throw new InvalidOperationException();
            }
            if (prop.Parameters.Count > 0)             //indexer
            {
                if (IsTypedVector(method))
                {
                    code.GetProperty(code.Abc.NameArrayIndexer);
                    code.Coerce(method.Type, true);
                }
                else
                {
                    code.GetNativeArrayItem();
                }
            }
            else
            {
                code.GetProperty(prop.Name);
            }
        }
Пример #4
0
        private IEnumerable <IInstruction> SetNull(IType type, IVariable var)
        {
            EnsureType(type);
            var code = new AbcCode(_abc);

            code.PushNull();
            code.Coerce(type, true);
            code.AddRange(StoreVariable(var));
            return(code);
        }
Пример #5
0
        public static void Ctor(IMethod method, AbcCode code)
        {
            var vec = method.DeclaringType.Data as IVectorType;

            if (vec == null)
            {
                throw new InvalidOperationException();
            }
            code.Construct(method.Parameters.Count);
            code.Coerce(vec.Name);
        }
Пример #6
0
        private void Call(AbcCode code, IMethod method, AbcMultiname prop, CallFlags flags)
        {
            if (prop == null)
            {
                throw new ArgumentNullException("prop");
            }

            CallCore(code, method, prop, flags);

            if (MustCoerceReturnType(method))
            {
                var type = method.Type;
                EnsureType(type);
                code.Coerce(type, true);
            }
        }
Пример #7
0
        private static void TryUnboxNumber(AbcCode code, IType type)
        {
            const int varValue = 1;

            code.GetLocal(varValue);
            var ifNotNumber = code.IfType(AvmTypeCode.Number);

            code.ThrowInvalidCastException();
            ifNotNumber.BranchTarget = code.Label();
            code.GetLocal(varValue);
            if (!code.TryCastToSystemType(null, type.SystemType()))
            {
                code.Coerce(type, true);
            }
            code.ReturnValue();
        }
Пример #8
0
        public static void GetItem2(IMethod method, AbcCode code)
        {
            var p0 = method.Parameters[0].Type;

            if (p0.Name == "Namespace")
            {
                code.GetRuntimeProperty();
                code.CoerceXMLList();
            }
            else                               //namespace as Avm.String
            {
                code.Swap();                   //stack [name, nsname]
                var ns = code[AvmTypeCode.Namespace];
                code.FindPropertyStrict(ns);   //stack [name, nsname, global]
                code.Swap();                   //stack [name, global, nsname]
                code.ConstructProperty(ns, 1); //stack [name, ns]
                code.Coerce(ns);               //stack [name, ns]
                code.Swap();                   //stack [ns, name]
                code.GetRuntimeProperty();
                code.CoerceXMLList();
            }
        }
Пример #9
0
        void RouteException(AbcCode code, ISehHandlerBlock block, int var)
        {
            var exceptionType = block.ExceptionType;

            if (block.PrevHandler == null)
            {
                //if err is AVM error then we translate it to System.Exception.
                //code.GetLocal(var);
                //code.As(AvmTypeCode.Error);
                //code.PushNull();
                //var ifNotError = code.IfEquals();

                code.GetLocal(var);
                code.As(SystemTypes.Exception, true);
                code.PushNull();
                var ifExc = code.IfNotEquals();

                code.GetLocal(var);
                code.As(AvmTypeCode.Error);
                code.PushNull();
                var ifNotError = code.IfEquals();

                CallToException(code, var);
                code.CoerceAnyType();
                code.SetLocal(var);

                //check my exception
                var labelNotError = code.Label();
                ifExc.BranchTarget      = labelNotError;
                ifNotError.BranchTarget = labelNotError;
            }

            code.GetLocal(var);

            var handlerInfo = (SehHandlerInfo)block.Tag;

            handlerInfo.CheckExceptionLabel = code.Label();
            //NOTE: Exception on stack can be routed from previous handlers
            code.SetLocal(var);
            code.GetLocal(var);
            code.As(exceptionType, true);
            code.PushNull();
            var ifMyException = code.IfNotEquals();

            //Routing to another exception handler or rethrow
            //Instruction routing = Label();
            if (block.NextHandler == null)
            {
                code.GetLocal(var);
                code.Throw();
            }
            else
            {
                code.GetLocal(var);
                handlerInfo.JumpToNextHandler = code.Goto();
            }

            //Normal Execution: Prepare stack for handler
            var normal = code.Label();

            ifMyException.BranchTarget = normal;

            code.GetLocal(var);
            code.Coerce(exceptionType, true);

            //21 instructions for first handler
            //11 instructions for other handlers
        }