Beispiel #1
0
        public static string GetOverloadedMethodName(this MethodReference method)
        {
            var index = method.GetMethodOverloadIndex();

            if (index >= 1)
            {
                // Atmark will replace to underscore by ManglingSymbolName()
                return(string.Format(
                           "{0}@{1}",
                           method.Name,
                           index));
            }

            return(method.Name);
        }
Beispiel #2
0
        public override Func <IExtractContext, string[]> Apply(
            MethodReference method, DecodeContext decodeContext)
        {
            var md = method.Resolve();

            if (!md.IsConstructor)
            {
                throw new InvalidProgramSequenceException(
                          "Invalid new object constructor: Offset={0}, Method={1}",
                          decodeContext.Current.Offset,
                          md.GetFullMemberName());
            }

            var pairParameters = md.Parameters
                                 .Reverse()
                                 .Select(parameter => new Utilities.RightExpressionGivenParameter(
                                             parameter.ParameterType, decodeContext.PopStack()))
                                 .Reverse()
                                 .ToList();
            var overloadIndex = method.GetMethodOverloadIndex();

            var type           = md.DeclaringType;
            var thisSymbolName = decodeContext.PushStack(type);

            // Insert this reference.
            pairParameters.Insert(0,
                                  new Utilities.RightExpressionGivenParameter(
                                      type, new SymbolInformation(thisSymbolName, type)));

            var offset = decodeContext.Current.Offset;

            return(extractContext =>
            {
                var parameterString = Utilities.GetGivenParameterDeclaration(
                    pairParameters.ToArray(), extractContext, offset);

                // newobj opcode can handle value type with parameter applied constructor.
                if (type.IsValueType)
                {
                    var typeName = extractContext.GetCLanguageTypeName(
                        type);
                    // If constructor's arguments greater than or equal 2 (this and others)
                    if (pairParameters.Count >= 2)
                    {
                        return new[] {
                            string.Format(
                                "memset(&{0}, 0x00, sizeof({1}))",
                                thisSymbolName,
                                typeName),
                            (overloadIndex >= 1)
                                ? string.Format(
                                "{0}__ctor_{1}(&{2})",
                                typeName,
                                overloadIndex,
                                parameterString)
                                : string.Format(
                                "{0}__ctor(&{1})",
                                typeName,
                                parameterString)
                        };
                    }
                    else
                    {
                        // ValueType's default constructor not declared.
                        return new[] { string.Format(
                                           "memset(&{0}, 0x00, sizeof({1}))",
                                           thisSymbolName,
                                           typeName) };
                    }
                }
                // Object reference types.
                else
                {
                    var dereferencedTypeName = extractContext.GetCLanguageTypeName(
                        type, TypeNameFlags.Dereferenced);

                    var get = new[]
                    {
                        string.Format(
                            "{0} = il2c_get_uninitialized_object(il2c_typeof({1}))",
                            thisSymbolName,
                            dereferencedTypeName)
                    };

                    // Setup vptr from vtables.
                    var vptr = new[]
                    {
                        // Instance's vptr
                        string.Format(
                            "{0}->vptr0__ = &__{1}_VTABLE__",
                            thisSymbolName,
                            dereferencedTypeName)
                    }.Concat(type.Interfaces.Select(interfaceImpl =>
                    {
                        // Interface's vptr:
                        //   These are unique tables by pair of instance type and interface type.
                        //   Because vtable has function pointers from unique adjustor thunk by instance type layout offset.
                        var tn = extractContext.GetCLanguageTypeName(
                            interfaceImpl.InterfaceType, TypeNameFlags.Dereferenced);
                        return string.Format(
                            "{0}->vptr_{1}__ = &__{2}_{1}_VTABLE__",
                            thisSymbolName,
                            tn,
                            dereferencedTypeName);
                    }));

                    var ctor = new[]
                    {
                        (overloadIndex >= 1)
                            ? string.Format(
                            "{0}__ctor_{1}({2})",
                            dereferencedTypeName,
                            overloadIndex,
                            parameterString)
                            : string.Format(
                            "{0}__ctor({1})",
                            dereferencedTypeName,
                            parameterString)
                    };

                    return get
                    .Concat(vptr)
                    .Concat(ctor)
                    .ToArray();
                }
            });
        }