Пример #1
0
        static void CreateCdRslArray(AbcCode code, IList <RslItem> rsls)
        {
            int n = rsls.Count;

            for (int i = 0; i < n; ++i)
            {
                var rsl = rsls[i];
                code.PushString("rsls");
                code.PushStringArray(new[] { rsl.Uri });

                code.PushString("policyFiles");
                code.PushStringArray(rsl.PolicyFiles);

                code.PushString("digests");
                string digest = rsl.Swc.GetLibraryDigest(null, rsl.HashType, rsl.IsSigned);
                if (string.IsNullOrEmpty(digest))
                {
                    throw Errors.RSL.UnableToResolveLibraryDigest.CreateException(rsl.LocalPath);
                }
                code.PushStringArray(new[] { digest });

                code.PushString("types");
                code.PushStringArray(new[] { rsl.HashType });

                code.PushString("isSigned");
                code.PushNativeBool(rsl.IsSigned);
                code.Add(InstructionCode.Newarray, 1);

                code.NewObject(5);
            }
            code.Add(InstructionCode.Newarray, n);
        }
Пример #2
0
 private static void ToFlatIndex(AbcCode code, int n, bool getter)
 {
     code.LoadThis();
     if (getter)
     {
         code.LoadArguments(n);
         code.Add(InstructionCode.Newarray, n);
     }
     else
     {
         //Last argument is a value
         code.GetLocals(1, n - 1);
         code.Add(InstructionCode.Newarray, n - 1);
     }
     code.Call(ArrayMethodId.ToFlatIndex);
 }
Пример #3
0
        /// <summary>
        /// Calls entry point (Main method).
        /// //NOTE: This method always adds return instruction
        /// </summary>
        /// <param name="code"></param>
        internal void CallEntryPoint(AbcCode code)
        {
            //Note: in swf entry point will be called in ctor of root sprite
            if (EntryPoint == null)
            {
                code.ReturnVoid();
                return;
            }

            var main = EntryPoint.AbcMethod();

            if (main == null)
            {
                throw new InvalidOperationException("Invalid entry point");
            }

            code.Getlex(main);

            if (AbcGenConfig.ParameterlessEntryPoint)
            {
                code.Add(InstructionCode.Callpropvoid, main.TraitName, 0);
                code.ReturnVoid();
            }
            else
            {
                //TODO: pass process args
                int n = EntryPoint.Parameters.Count;
                for (int i = 0; i < n; ++i)
                {
                    //code.GetLocal(i + 1);
                    code.PushNull();
                }

                bool isVoid = EntryPoint.IsVoid();
                if (isVoid || IsSwf)
                {
                    code.Add(InstructionCode.Callpropvoid, main.Trait.Name, n);
                    code.ReturnVoid();
                }
                else
                {
                    code.Add(InstructionCode.Callproperty, main.Trait.Name, n);
                    code.ReturnValue();
                }
            }
        }
Пример #4
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));
        }
Пример #5
0
        public IEnumerable <IInstruction> InvokeDelegate(IMethod method)
        {
            var code = new AbcCode(_abc)
            {
                { InstructionCode.Call, method.Parameters.Count }
            };

            if (method.IsVoid())
            {
                code.Add(InstructionCode.Pop);
            }
            return(code);
        }
Пример #6
0
 public static void NewArray(IMethod method, AbcCode code)
 {
     if (method.Parameters.Count == 1)
     {
         //size is onto the stack
         code.Getlex(AvmTypeCode.Array);
         code.Swap();
         code.Construct(1);
         code.CoerceArray();
         return;
     }
     code.Add(InstructionCode.Newarray, 0);
 }
Пример #7
0
        public static void Concat(IMethod method, AbcCode code)
        {
            int n = method.Parameters.Count;

            if (n <= 1)
            {
                throw new InvalidOperationException();
            }
            for (int i = 1; i < n; ++i)
            {
                code.Add(InstructionCode.Add);
            }
            code.CoerceString();
        }
Пример #8
0
        private int SetTempVar(AbcCode code, bool keepStackState)
        {
            //NOTE: we duplicate value onto the stack to keep stack unchanged after this operation
            if (keepStackState)
            {
                code.Add(InstructionCode.Dup);
            }

            int var = NewTempVar(false);

            code.SetLocal(var);

            return(var);
        }
Пример #9
0
 private bool SuperCall(AbcCode code, IMethod method)
 {
     if (IsConstructSuper(method))
     {
         int n = method.Parameters.Count;
         if (ShouldPopBaseCtorCall(method))
         {
             code.Pop(n + 1);
         }
         else
         {
             code.Add(InstructionCode.Constructsuper, n);
         }
         return(true);
     }
     return(false);
 }
Пример #10
0
        static void CreateSimpleRslArray(AbcCode code, IList <RslItem> rsls)
        {
            int n = rsls.Count;

            for (int i = 0; i < n; ++i)
            {
                var rsl = rsls[i];
                code.PushString("url");
                code.PushString(rsl.Uri);

                code.PushString("size");
                code.PushInt(-1);

                code.NewObject(2);
            }
            code.Add(InstructionCode.Newarray, n);
        }
Пример #11
0
 void KillExceptionVariable(AbcCode code, CatchInfo ci)
 {
     if (!ci.IsVarKilled)
     {
         ci.IsVarKilled = true;
         if (ci.IsTempVar)
         {
             code.Add(KillTempVarCore(ci.ExceptionVar));
         }
         else
         {
             //NOTE: Fix to avoid VerifyError when types can not be reconciled.
             //code.PushUndefined();
             //code.SetLocal(ci.ExceptionVar);
             //code.Add(InstructionCode.Kill, ci.varExc);
         }
     }
 }
Пример #12
0
 public static void ReferenceEquals(AbcCode code)
 {
     code.Add(InstructionCode.Strictequals);
     code.FixBool();
 }
Пример #13
0
 public static void op_Inequality(AbcCode code)
 {
     code.Add(InstructionCode.Equals);
     code.Add(InstructionCode.Not);
     code.FixBool();
 }
Пример #14
0
 public static void IsNull(AbcCode code)
 {
     code.PushNull();
     code.Add(InstructionCode.Equals);
     code.FixBool();
 }
Пример #15
0
        private AbcMethod BuildCtorImpl(IMethod method, AbcInstance instance)
        {
            if (!method.IsConstructor)
            {
                return(null);
            }
            if (method.IsStatic)
            {
                return(null);
            }
            var type = method.DeclaringType;

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

            var ctor = new AbcMethod
            {
                ReturnType = Abc.BuiltinTypes.Void
            };

            _generator.MethodBuilder.BuildParameters(ctor, method);

            string name1 = "arrctor_" + type.GetSigName();
            var    name  = Abc.DefineName(QName.Global(name1));
            var    trait = AbcTrait.CreateMethod(ctor, name);

            instance.Traits.Add(trait);

            var body = new AbcMethodBody(ctor);

            Abc.AddMethod(ctor);

            var code = new AbcCode(Abc);

            code.PushThisScope();
            code.ConstructSuper();

            //check arguments
            int n = method.Parameters.Count;

            for (int i = 0; i < n; ++i)
            {
                code.GetLocal(i + 1);
                code.PushInt(0);
                var br            = code.If(BranchOperator.GreaterThanOrEqual);
                var exceptionType = _generator.Corlib.GetType(CorlibTypeId.ArgumentOutOfRangeException);
                code.ThrowException(exceptionType);
                br.BranchTarget = code.Label();
            }

            //m_rank = n
            code.LoadThis();
            code.PushInt(n);
            code.SetProperty(Const.Array.Rank);

            int varSize = n + 1;

            for (int i = 0; i < n; ++i)
            {
                code.GetLocal(i + 1);
            }
            for (int i = 1; i < n; ++i)
            {
                code.Add(InstructionCode.Multiply_i);
            }
            code.SetLocal(varSize);

            //init m_value
            code.LoadThis();
            code.CreateArrayVarSize(varSize);
            code.SetProperty(Const.Array.Value);

            //init m_lengths
            code.LoadThis();
            for (int i = 0; i < n; ++i)
            {
                code.GetLocal(i + 1);
            }
            code.Add(InstructionCode.Newarray, n);
            code.SetProperty(Const.Array.Lengths);

            int varDimArr = varSize + 1;

            //init m_dims
            code.CreateArray(n - 1);
            code.SetLocal(varDimArr);

            //1, n, n * (n-1), ..., n * (n-1) * ... * n0
            for (int i = n - 2; i >= 0; --i)
            {
                int leni = i + 2;
                code.GetLocal(varDimArr);
                code.PushInt(i);

                if (i != n - 2)
                {
                    code.GetLocal(varDimArr);
                    code.PushInt(i + 1);
                    code.GetNativeArrayItem();
                    code.CoerceInt32();                     //prev

                    code.GetLocal(leni);
                    code.Add(InstructionCode.Multiply_i);                     //prev * leni
                }
                else
                {
                    code.GetLocal(leni);
                }

                code.SetNativeArrayItem();
            }

            code.LoadThis();
            code.GetLocal(varDimArr);
            code.SetProperty(Const.Array.Dims);

            var elemType = type.GetElementType();

            InitFields(code, type, elemType, 0);

            if (InternalTypeExtensions.IsInitArray(elemType))
            {
                code.InitArray(elemType,
                               () =>
                {
                    code.LoadThis();
                    code.GetProperty(Const.Array.Value);
                }, varSize);
            }

            code.ReturnVoid();

            body.Finish(code);

            return(ctor);
        }
Пример #16
0
 public static void IsUndefined(AbcCode code)
 {
     code.PushUndefined();
     code.Add(InstructionCode.Equals);
     code.FixBool();
 }
Пример #17
0
        private void CallCore(AbcCode code, IMethod method, AbcMultiname prop, bool super)
        {
            var abcMethod = method.AbcMethod();

            if (abcMethod != null)
            {
                if (abcMethod.IsGetter)
                {
                    code.Add(super ? InstructionCode.Getsuper : InstructionCode.Getproperty, prop);
                    return;
                }

                if (abcMethod.IsSetter)
                {
                    code.Add(super ? InstructionCode.Setsuper : InstructionCode.Setproperty, prop);
                    return;
                }
            }

            int n = method.Parameters.Count;

            if (method.AsStaticCall())
            {
                ++n;
            }

            bool isVoid = method.IsVoid();

            if (CanUseCallStatic)
            {
                if (method.IsStaticCall() &&
                    method.IsManaged() &&
                    abcMethod != null && _abc.IsDefined(abcMethod))
                {
                    code.Add(InstructionCode.Callstatic, abcMethod, n);
                    if (isVoid)
                    {
                        code.Pop();
                    }
                    return;
                }
            }

            if (super)
            {
                if (isVoid)
                {
                    code.Add(InstructionCode.Callsupervoid, prop, n);
                    return;
                }
                code.Add(InstructionCode.Callsuper, prop, n);
                return;
            }

            if (isVoid)
            {
                code.Add(InstructionCode.Callpropvoid, prop, n);
                return;
            }

            code.Add(InstructionCode.Callproperty, prop, n);
        }
Пример #18
0
 public static void Equals(AbcCode code)
 {
     code.Add(InstructionCode.Equals);
     code.FixBool();
 }
Пример #19
0
        public IEnumerable <IInstruction> Branch(BranchOperator op, IType left, IType right)
        {
            if (op.IsUnary())
            {
                if (op == BranchOperator.Null)
                {
                    var code = new AbcCode(_abc);
                    //NOTE: old code - not working with nullable types
                    //code.PushNull();
                    //code.Add(InstructionCode.Ifeq);
                    code.IsNull(left, right);
                    code.Add(InstructionCode.Iftrue);
                    return(code);
                }

                if (op == BranchOperator.NotNull)
                {
                    var code = new AbcCode(_abc);
                    //NOTE: old code - not working with nullable types
                    //code.PushNull();
                    //code.Add(InstructionCode.Ifne);
                    code.IsNull(left, right);
                    code.Add(InstructionCode.Iffalse);
                    return(code);
                }

                if (left.IsDecimalOrInt64())
                {
                    var  code   = new AbcCode(_abc);
                    bool isTrue = op == BranchOperator.True;
                    var  abcOp  = _generator.Operators.BuildBoolOp(left, isTrue);
                    //TODO: Should we enshure not null value onto the stack???
                    //AbcMethod abcOp = _generator.DefineTruthOperator(left, isTrue);
                    //code.LoadStaticReceiver(abcOp);
                    //code.Swap();
                    code.Call(abcOp);
                    code.Add(isTrue ? InstructionCode.Iftrue : InstructionCode.Iffalse);
                    return(code);
                }
            }
            else if (InternalTypeExtensions.IsDecimalOrInt64(left, right))
            {
                var code = new AbcCode(_abc);
                var opm  = _generator.Operators.Build(op, left, right);
                code.Call(opm);
                code.Add(InstructionCode.Iftrue);
                return(code);
            }

            switch (op)
            {
            case BranchOperator.True:
                return(If(InstructionCode.Iftrue));

            case BranchOperator.False:
                return(If(InstructionCode.Iffalse));

            case BranchOperator.Equality:
                return(If(InstructionCode.Ifeq));

            case BranchOperator.Inequality:
                return(If(InstructionCode.Ifne));

            case BranchOperator.LessThan:
                return(If(InstructionCode.Iflt));

            case BranchOperator.LessThanOrEqual:
                return(If(InstructionCode.Ifle));

            case BranchOperator.GreaterThan:
                return(If(InstructionCode.Ifgt));

            case BranchOperator.GreaterThanOrEqual:
                return(If(InstructionCode.Ifge));

            default:
                throw new NotSupportedException();
            }
        }