コード例 #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 void CompleteMethod(AbcInstance instance, IMethod method, AbcMethod abcMethod)
 {
     BuildBody(abcMethod);
     BuildImplementedMethods(method, instance, abcMethod);
     BuildOverrideMethods(method, abcMethod);
     ImplementProtoMethods(method, abcMethod);
 }
コード例 #3
0
        /// <summary>
        /// Creates cast_to_type method via given AS method
        /// </summary>
        /// <param name="type"></param>
        /// <param name="AS"></param>
        /// <returns></returns>
        private AbcMethod Impl(IType type, AbcMethod AS, AbcMultiname name)
        {
            var instance = AS.Instance;

            var typeName = _generator.TypeBuilder.BuildMemberType(type);

            return(instance.DefineMethod(
                       Sig.@static(name, typeName, AvmTypeCode.Object, "value"),
                       code =>
            {
                const int value = 1;

                code.GetLocal(value);
                code.IfNullReturnNull(1);

                code.Getlex(instance);
                code.GetLocal(value);
                code.Call(AS);
                code.SetLocal(value);

                code.GetLocal(value);
                var notNull = code.IfNotNull(false);
                code.ThrowInvalidCastException(type);

                notNull.BranchTarget = code.Label();
                code.GetLocal(value);
                code.ReturnValue();
            }));
        }
コード例 #4
0
        private static bool HasFlashIfaceName(AbcMethod method)
        {
            var mn = method.TraitName;

            if (mn == null)
            {
                return(false);
            }
            if (!mn.IsQName)
            {
                return(false);
            }
            if (mn.Namespace.Kind != AbcConstKind.PublicNamespace)
            {
                return(false);
            }

            var instance = method.Instance;

            if (instance == null)
            {
                return(false);
            }
            if (!instance.Name.IsQName)
            {
                return(false);
            }

            var ns   = instance.Name.Namespace.NameString;
            var name = instance.Name.NameString;

            ns = string.IsNullOrEmpty(ns) ? name : ns + ":" + name;

            return(mn.Namespace.NameString == ns);
        }
コード例 #5
0
        internal void CopyParameters(AbcMethod to, AbcMethod from)
        {
            int n = from.Parameters.Count;

            for (int i = 0; i < n; ++i)
            {
                var bp = from.Parameters[i];
                var ap = new AbcParameter
                {
                    Type = Abc.ImportConst(bp.Type),
                    Name = Abc.ImportConst(bp.Name)
                };
                if (bp.IsOptional)
                {
                    ap.IsOptional        = true;
                    ap.Value             = Abc.ImportValue(bp.Value);
                    to.HasOptionalParams = true;
                }
                to.Parameters.Add(ap);
            }
            if (from.NeedRest)
            {
                to.NeedRest = true;
            }
        }
コード例 #6
0
        private void BuildOverrideMethods(IMethod method, AbcMethod abcMethod)
        {
            if (!method.IsAbstract && !method.IsVirtual)
            {
                return;
            }

            var type     = method.DeclaringType;
            var instance = type.AbcInstance();

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

            if (instance.IsInterface)
            {
                //TODO: fix this problem
                //warning: do not use for each since instance.Implementations is modifiable.
                for (int i = 0; i < instance.Implementations.Count; ++i)
                {
                    var impl = instance.Implementations[i];
                    BuildImplementation(impl, impl.Type, method, abcMethod);
                }
            }
            else
            {
                BuildSubclassOverrideMethods(instance, method);
            }
        }
コード例 #7
0
        /// <summary>
        /// Defines parameters for given <see cref="AbcMethod"/>.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="source">source method of given <see cref="AbcMethod"/></param>
        public void BuildParameters(AbcMethod target, IMethod source)
        {
            if (source == _generator.EntryPoint)
            {
                if (AbcGenConfig.ParameterlessEntryPoint)
                {
                    return;
                }
            }

            if (source.HasPseudoThis())
            {
                target.Parameters.Add(Abc.CreateParameter(source.DeclaringType, "this"));
            }

            var abm = GetBaseMethod(target, source);

            if (abm != null)
            {
                CopyParameters(target, abm);
            }
            else
            {
                target.Parameters.AddRange(source.Parameters.Select(p => Abc.CreateParameter(p.Type, p.Name)));
            }
        }
コード例 #8
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);
        }
コード例 #9
0
        private static void WriteParams(TextWriter writer, AbcMethod method)
        {
            writer.Write("(");
            int n = method.Parameters.Count;

            for (int i = 0; i < n; ++i)
            {
                if (i > 0)
                {
                    writer.Write(", ");
                }
                var p = method.Parameters[i];
                WriteQName(writer, p.Type);
                writer.Write(" ");
                if (p.HasName)
                {
                    writer.Write(p.Name.Value);
                }
                else
                {
                    writer.Write("arg{0}", i);
                }
            }
            if ((method.Flags & AbcMethodFlags.NeedRest) != 0)
            {
                if (n > 0)
                {
                    writer.Write(", ");
                }
                writer.Write("params object[] rest");
            }
            writer.Write(")");
        }
コード例 #10
0
        /// <summary>
        /// Compiles <see cref="IMethod.Implements"/> methods.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="instance"></param>
        /// <param name="abcMethod"></param>
        private void BuildImplementedMethods(IMethod method, AbcInstance instance, AbcMethod abcMethod)
        {
            var impls = method.Implements;

            if (impls == null)
            {
                return;
            }

            int n = impls.Count;

            if (n <= 0)
            {
                return;
            }

            //NOTE: To avoid conflict with name of explicit implementation method has the same name as iface method
            if (method.IsExplicitImplementation)
            {
                Build(impls[0]);
                return;
            }

            if (n == 1 && !abcMethod.IsOverride)
            {
                Build(impls[0]);
                return;
            }

            foreach (var ifaceMethod in impls)
            {
                var ifaceAbcMethod = BuildAbcMethod(ifaceMethod);
                BuildExplicitImplementation(instance, abcMethod, ifaceMethod, ifaceAbcMethod);
            }
        }
コード例 #11
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);
        }
コード例 #12
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);
            });
        }
コード例 #13
0
 private static void AddEventListener(AbcCode code, AbcMethod method, string eventName)
 {
     code.LoadThis();
     code.PushString(eventName);
     code.LoadThis();
     code.GetProperty(method.TraitName);
     code.CallVoid("addEventListener", 2);
 }
コード例 #14
0
        public static XElement ToXml(this AbcMethod method)
        {
            var res = new XElement("method");

            if (!string.IsNullOrWhiteSpace(method.Name))
            {
                res.Add(new XAttribute("name", method.Name));
            }

            var retType = method.ReturnType.ToXml();

            if (!string.IsNullOrWhiteSpace(retType))
            {
                res.Add(new XAttribute("returns", retType));
            }

            if (method.NeedArguments)
            {
                res.Add(new XAttribute("needArguments", CommonFormatter.Format(method.NeedArguments)));
            }
            if (method.NeedActivation)
            {
                res.Add(new XAttribute("needActivation", CommonFormatter.Format(method.NeedActivation)));
            }
            if (method.NeedRest)
            {
                res.Add(new XAttribute("needRest", CommonFormatter.Format(method.NeedRest)));
            }
            if (method.SetDxns)
            {
                res.Add(new XAttribute("setDxns", CommonFormatter.Format(method.SetDxns)));
            }
            if (method.IgnoreRest)
            {
                res.Add(new XAttribute("ignoreRest", CommonFormatter.Format(method.IgnoreRest)));
            }
            if (method.Native)
            {
                res.Add(new XAttribute("native", CommonFormatter.Format(method.Native)));
            }

            if (method.Params.Count > 0)
            {
                var xParams = new XElement("params");
                foreach (var param in method.Params)
                {
                    xParams.Add(ToXml(param));
                }
                res.Add(xParams);
            }
            if (method.Body != null)
            {
                res.Add(ToXml(method.Body));
            }

            return(res);
        }
コード例 #15
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);
        }
コード例 #16
0
        private static void OverrideExplicitImplsInSubclasses(AbcInstance instance, AbcMethod ifaceMethod)
        {
            var name = ifaceMethod.TraitName;

            foreach (var c in instance.Subclasses)
            {
                var t = c.Traits.Find(name, ifaceMethod.Trait.Kind);
                if (t != null)
                {
                    t.IsOverride = true;
                }
            }
        }
コード例 #17
0
        public AbcMultiname BuildReturnType(AbcMethod abcMethod, IMethod method)
        {
            if (method.IsConstructor && method.AsStaticCall())
            {
                return(_generator.TypeBuilder.BuildMemberType(method.DeclaringType));
            }

            var bm = GetBaseMethod(abcMethod, method);

            if (bm != null)
            {
                return(bm.ReturnType);
            }

            return(_generator.TypeBuilder.BuildReturnType(method.Type));
        }
コード例 #18
0
        private object Import(AbcMethod method)
        {
            if (method.IsNative)
            {
                return(method);
            }

            var abc = method.Abc;

            if (abc.IsCore)
            {
                return(method);
            }

            if (method.ImportedMethod != null)
            {
                return(method.ImportedMethod);
            }

            var instance = method.Instance;

            if (instance != null)
            {
                var i2 = Abc.ImportInstance(instance, ref method);
                if (i2 == null)
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                if (!(method.Owner is AbcScript))
                {
                    throw new InvalidOperationException();
                }

                Abc.Import(abc);

                //NOTE: ABC can be linked externally
                if (method.ImportedMethod != null)
                {
                    return(method.ImportedMethod);
                }
            }

            return(method);
        }
コード例 #19
0
        private AbcMethod GetBaseMethod(AbcMethod abcMethod, IMethod method)
        {
            var impls = method.Implements;

            if (impls != null && impls.Count == 1)
            {
                return(BuildAbcMethod(impls[0]));
            }

            var baseMethod = method.BaseMethod;

            if (abcMethod.IsOverride && baseMethod != null)
            {
                return(baseMethod.AbcMethod());
            }

            return(null);
        }
コード例 #20
0
        private static void LinkMethod(IMethod method, AbcMethod abcMethod)
        {
            if (abcMethod == null)
            {
                throw new InvalidOperationException("Unable to find method " + method);
            }

            method.Data = abcMethod;

            //Prevent to link overload methods
            if (method.Parameters.Count == abcMethod.ActualParamCount)
            {
                abcMethod.Method = method;
            }

            //var instance = abcMethod.Instance;
            //if (instance != null && !instance.IsNative && abcMethod.IsNative)
            //    instance.IsNative = true;
        }
コード例 #21
0
        private void BuildBody(AbcMethod abcMethod)
        {
            if (abcMethod == null)
            {
                throw new ArgumentNullException();
            }

            var method = abcMethod.Method;

            if (method == null)
            {
                return;
            }
            if (method.Body == null)
            {
                return;
            }

            BuildBodyCore(abcMethod, method);
        }
コード例 #22
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;
            }
        }
コード例 #23
0
        public void Implement(IMethod method, AbcMethod abcMethod)
        {
            if (method == null)
            {
                return;
            }
            if (method.IsStatic)
            {
                return;
            }
            if (method.IsConstructor)
            {
                return;
            }
            var declType = method.DeclaringType;

            if (!declType.Is(SystemTypeCode.Object))
            {
                return;
            }

            DefinePrototype(AvmTypeCode.Object, abcMethod);
            DefinePrototype(AvmTypeCode.String, abcMethod);
        }
コード例 #24
0
ファイル: XAbcOpcodeExts.cs プロジェクト: shhadi/SwfLib
 public static XElement AddMethod(this XElement node, AbcMethod method)
 {
     node.Add(new XAttribute("method", method.Name));
     return(node);
 }
コード例 #25
0
        private AbcMethod DefineTestRunner(IMethod test)
        {
            var method = _generator.MethodBuilder.BuildAbcMethod(test);

            var    instance = method.Instance;
            string name     = "run_test_" + test.GetMonoTestCaseName();

            name = name.Replace('.', '_');

            return(instance.DefineMethod(
                       Sig.@static(name, AvmTypeCode.Void, GetInstance(NUnitTypeId.Test)),
                       code =>
            {
                var testFixture = test.DeclaringType;
                const int varTF = 2;
                const int varErr = 3;

                //TODO: Redirect Console, Debug output

                var ee = test.GetExpectedExceptionType();
                var setup = testFixture.GetUnitTestSetup();
                AbcMethod setupAM = null;
                if (setup != null)
                {
                    setupAM = _generator.MethodBuilder.BuildAbcMethod(setup);
                }

                Test_Success(code, true);
                Test_Executed(code, true);

                code.ConsoleOpenSW();

                code.Try();

                #region setup & call
                if (test.IsStatic)
                {
                    if (setup != null && setup.IsStatic)
                    {
                        code.Getlex(setupAM);
                        code.Call(setupAM);
                    }

                    code.Getlex(method);
                    code.Call(method);
                }
                else
                {
                    code.CreateInstance(testFixture, true);
                    code.CoerceAnyType();
                    code.SetLocal(varTF);

                    if (setup != null)
                    {
                        code.GetLocal(varTF);
                        code.Call(setupAM);
                    }

                    code.GetLocal(varTF);
                    code.Call(method);
                }
                #endregion

                if (ee != null)
                {
                    code.ConsoleCloseSW(true);
                    Test_Success(code, false);
                    Test_Output(code, "No expected exception: {0}", ee.FullName);
                }
                else
                {
                    Test_Output(code, () => code.ConsoleCloseSW(false));
                }

                code.ReturnVoid();

                if (ee != null)
                {
                    code.BeginCatch(_generator.TypeBuilder.BuildInstance(ee), false);
                    code.Pop();
                    Test_Success(code, true);
                    Test_Output(code, () => code.ConsoleCloseSW(false));
                    code.ReturnVoid();
                    code.EndCatch(false);
                }

                code.BeginCatch();
                code.CoerceAnyType();
                code.SetLocal(varErr);
                code.ConsoleCloseSW(true);
                Test_Success(code, false);
                Test_Output(
                    code,
                    () =>
                {
                    code.PushString("Unexpected exception: ");
                    code.GetLocal(varErr);
                    code.GetErrorMessage();
                    code.Add(InstructionCode.Add);
                });
                Test_StackTrace(
                    code,
                    () =>
                {
                    code.GetLocal(varErr);
                    code.GetErrorStackTrace();
                });
                code.EndCatch(true);

                code.ReturnVoid();
            }));
        }
コード例 #26
0
 private void ImplementProtoMethods(IMethod method, AbcMethod abcMethod)
 {
     _generator.StringPrototypes.Implement(method);
     _generator.ObjectPrototypes.Implement(method, abcMethod);
 }
コード例 #27
0
 internal void AddLateMethod(AbcMethod method, AbcCoder coder)
 {
     _lateMethods.Add(method, coder);
 }
コード例 #28
0
        internal void BuildImplementation(AbcInstance implInstance, IType implType, IMethod ifaceMethod, AbcMethod ifaceAbcMethod)
        {
            if (implInstance == null)
            {
                throw new ArgumentNullException("implInstance");
            }
            if (implInstance.IsInterface)
            {
                return;
            }

            if (implType == null)
            {
                throw new ArgumentNullException("implType");
            }
            if (implType.IsInterface)
            {
                return;
            }

            var impl = implType.FindImplementation(ifaceMethod, true, false);

            if (impl == null)
            {
                throw new InvalidOperationException(
                          string.Format("Unable to find implementation for method {0} in type {1}",
                                        ifaceMethod.FullName, implType.FullName));
            }

            impl = impl.ResolveGenericInstance(implType, ifaceMethod);

            var abcImpl = Build(impl) as AbcMethod;

            // determine whether we should create explicit impl
            if (abcImpl == null || implInstance.IsForeign ||
                ReferenceEquals(impl.DeclaringType, implType) ||
                impl.IsExplicitImplementation ||
                impl.Implements.Any(x => x == ifaceMethod))
            {
                return;
            }

            // do not create explicit impl if interface is implemented in base type
            var iface      = ifaceMethod.DeclaringType;
            var baseIfaces = implType.BaseTypes().SelectMany(x => x.Interfaces.SelectMany(i => i.Interfaces.Append(i)));

            if (baseIfaces.Any(x => ReferenceEquals(x, iface)))
            {
                return;
            }

            if (Equals(abcImpl.TraitName, ifaceAbcMethod.TraitName) ||
                (abcImpl.TraitName != null && ifaceAbcMethod.TraitName != null &&
                 abcImpl.TraitName.IsGlobalName(ifaceAbcMethod.TraitName.NameString) &&
                 HasFlashIfaceName(ifaceAbcMethod)))
            {
                return;
            }

            BuildExplicitImplementation(implInstance, abcImpl, ifaceMethod, ifaceAbcMethod);
        }
コード例 #29
0
        public void CacheCastOperator(IType source, IType target, AbcMethod op)
        {
            string key = GetCastOperatorKey(source, target);

            _cacheCastOps[key] = op;
        }
コード例 #30
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);
        }