コード例 #1
0
        private static AbcMethod BuildEnumCinit(AbcFile abc, IType type)
        {
            if (type == null)
            {
                return(null);
            }
            if (!type.IsEnum)
            {
                return(null);
            }

            var method = new AbcMethod {
                ReturnType = abc.BuiltinTypes.Void
            };
            var body = new AbcMethodBody(method);

            abc.AddMethod(method);

            var code = new AbcCode(abc);

            var generator = abc.Generator;

            foreach (var field in type.Fields.Where(field => field.IsConstant))
            {
                code.LoadThis();
                code.LoadConstant(field.Value);
                code.InitProperty(generator.FieldBuilder.GetFieldName(field));
            }

            code.ReturnVoid();

            body.Finish(code);

            return(method);
        }
コード例 #2
0
        public static Instruction Read(ILStream list, AbcMethodBody body, SwfReader reader)
        {
            int offset      = (int)reader.Position;
            var code        = (InstructionCode)reader.ReadUInt8();
            var instruction = Instructions.GetInstruction(code);

            instruction.Offset = offset;
            var ops = instruction.Operands;

            if (code == InstructionCode.Lookupswitch)
            {
                instruction.Operands[0].Value = reader.ReadInt24(); //default case offset
                int n = (int)reader.ReadUIntEncoded();              //max_index
                ops[1].Value = n;
                var cases = new int[n + 1];
                for (int i = 0; i <= n; ++i)
                {
                    cases[i] = reader.ReadInt24();
                }
                ops[2].Value = cases;
            }
            else if (ops != null)
            {
                int n = ops.Length;
                for (int i = 0; i < n; ++i)
                {
                    var op = ops[i];
                    op.Read(body, reader);
                }
            }
            return(instruction);
        }
コード例 #3
0
        public static XElement ToXml(this AbcMethodBody body)
        {
            var labels = new HashSet <uint>();

            body.ToXml(labels);
            return(body.ToXml(labels));
        }
コード例 #4
0
        private void BuildBodyCore(AbcMethod target, IMethod source)
        {
            var targetBody = target.Body;

            if (targetBody == null)
            {
                targetBody = new AbcMethodBody(target);
                Abc.MethodBodies.Add(targetBody);
            }

            var sourceBody = source.Body;

            var codeProvider = new CodeProviderImpl(_generator, target);

            var translator = sourceBody.CreateTranslator();

            if (translator == null)
            {
                throw new InvalidOperationException("No IL translator");
            }
            var il = translator.Translate(source, sourceBody, codeProvider);

            targetBody.IL.Add(il);
            targetBody.Finish(Abc);
        }
コード例 #5
0
 public void Read(AbcMethodBody body, SwfReader reader)
 {
     while (reader.Position < reader.Length)
     {
         var i = Instruction.Read(this, body, reader);
         i.Index = Count;
         Add(i);
     }
 }
コード例 #6
0
        //Generates method for script initializer
        private AbcMethod DefineMainScriptInit(AbcScript script, AbcInstance instance)
        {
#if DEBUG
            DebugService.LogInfo("DefineScriptInit started");
#endif

            var method = new AbcMethod();

            bool notSwf = !IsSwf;

            //Note: entry point also can contains arguments
            //Note: but in swf entry point can not have arguments
            if (EntryPoint != null && notSwf)
            {
                method.ReturnType = _generator.TypeBuilder.BuildReturnType(EntryPoint.Type);
                _generator.MethodBuilder.BuildParameters(method, EntryPoint);
            }

            var body = new AbcMethodBody(method);
            _generator.Abc.AddMethod(method);

            _mainScriptBody = body;

            var code = new AbcCode(Abc);

            _mainScriptCode = code;
            code.PushThisScope();
            code.InitClassProperties(script);

            //code.Trace("Initialization of " + instance.FullName);

            _insertIndexOfNewApi = code.Count;
            //code.AddRange(_newAPI);
            _generator.StaticCtors.Call(code, instance);

            if (notSwf) //abc?
            {
                _generator.NUnit.Main(code);
                CallEntryPoint(code);
            }
            else
            {
                code.ReturnVoid();
            }

            //body.Finish(code);

#if DEBUG
            DebugService.LogInfo("DefineScriptInit succeeded");
#endif
            return(method);
        }
コード例 #7
0
        public static XElement ToXml(this AbcMethodBody body, ISet <uint> labels)
        {
            var xBody = new XElement("body",
                                     new XAttribute("maxStack", body.MaxStack),
                                     new XAttribute("maxScopeDepth", body.MaxScopeDepth),
                                     new XAttribute("initScopeDepth", body.InitScopeDepth),
                                     new XAttribute("localCount", body.LocalCount)
                                     );

            if (body.Traits.Count > 0)
            {
                xBody.Add(body.Traits.ToXml());
            }

            Func <uint, string> labelFormatter = target => {
                labels.Add(target);
                return(string.Format("lbl_{0:x6}", target));
            };
            var writer = new XAbcOpcodeWriter(labelFormatter);

            var xCode = new XElement("code");

            foreach (var instruction in body.Code)
            {
                var xInstruction = instruction.Opcode.AcceptVisitor(writer, instruction);
                if (labels.Contains(instruction.Offset))
                {
                    xInstruction.Add(new XAttribute("label", string.Format("lbl_{0:x6}", instruction.Offset)));
                }
                xCode.Add(xInstruction);
            }
            xBody.Add(xCode);

            if (body.Exceptions.Count != 0)
            {
                var xExcs = new XElement("exceptions");
                foreach (var exc in body.Exceptions)
                {
                    var xExc = new XElement("exception",
                                            new XAttribute("from", labelFormatter(exc.From)),
                                            new XAttribute("to", labelFormatter(exc.To)),
                                            new XAttribute("target", labelFormatter(exc.Target)),
                                            new XAttribute("excType", exc.ExceptionType.ToXml()),
                                            new XAttribute("varName", exc.VariableName.ToXml()));
                    xExcs.Add(xExc);
                }
                xBody.Add(xExcs);
            }
            return(xBody);
        }
コード例 #8
0
        public CodeProviderImpl(AbcGenerator gen, AbcMethod abcMethod)
        {
            _generator = gen;
            _abc       = gen.Abc;
            _method    = abcMethod.Method;
            _body      = abcMethod.Body;
            _declType  = _method.DeclaringType;

            _asStatic = _method.AsStaticCall();

            //This code enshures initial capacity for local registers
            _body.LocalCount = _method.Parameters.Count + 1;
            var body = _method.Body;

            if (body == null)
            {
                throw new InvalidOperationException("method has no body");
            }

            if (HasPseudoThis)
            {
                _body.LocalCount++;
            }

            int n = VarCount;

            if (n == 0)
            {
                //NOTE: AVM constraint for LocalCount
                //if (local_count < info->param_count+1)
                //{
                // must have enough locals to hold all parameters including this
                //toplevel->throwVerifyError(kCorruptABCError);
                //}
                _body.LocalCount++;
            }
            else
            {
                _body.LocalCount += n;
            }
        }
コード例 #9
0
 public void Read(AbcMethodBody body, SwfReader reader)
 {
     Value = Read(body, reader, Type);
 }
コード例 #10
0
        public static object Read(AbcMethodBody body, SwfReader reader, OperandType type)
        {
            switch (type)
            {
            case OperandType.U30:
                return((int)reader.ReadUIntEncoded());

            case OperandType.S30:
                return(reader.ReadIntEncoded());

            case OperandType.U8:
                return(reader.ReadUInt8());

            case OperandType.U16:
                return(reader.ReadUInt16());

            case OperandType.U24:
                return(reader.ReadUInt24());

            case OperandType.U32:
                return(reader.ReadUInt32());

            case OperandType.S24:
            case OperandType.BranchTarget:
                return(reader.ReadInt24());

            case OperandType.ConstInt:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.IntPool[index]);
            }

            case OperandType.ConstUInt:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.UIntPool[index]);
            }

            case OperandType.ConstDouble:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.DoublePool[index]);
            }

            case OperandType.ConstString:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.StringPool[index]);
            }

            case OperandType.ConstMultiname:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.Multinames[index]);
            }

            case OperandType.ConstNamespace:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.Namespaces[index]);
            }

            case OperandType.MethodIndex:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.Methods[index]);
            }

            case OperandType.ClassIndex:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(reader.ABC.Classes[index]);
            }

            case OperandType.ExceptionIndex:
            {
                int index = (int)reader.ReadUIntEncoded();
                return(body.Exceptions[index]);
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #11
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);
        }