예제 #1
0
            public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
                var thisArgument = FixupThisArgument(arguments[1], translator.TypeSystem);

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                return new JSBinaryOperatorExpression(
                    JSOperator.Assignment,
                    JSDotExpression.New(
                        thisArgument,
                        new JSStringIdentifier(MemberName, returnType, true)
                    ),
                    arguments[2], returnType
                );
            }
예제 #2
0
            public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
                var thisArgument = arguments[1];

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                return new JSBinaryOperatorExpression(
                    JSOperator.Assignment,
                    new JSIndexerExpression(
                        thisArgument,
                        arguments[2],
                        returnType
                    ),
                    arguments[3], returnType
                );
            }
예제 #3
0
            public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                switch (Operation) {
                    case ExpressionType.Equal:
                    case ExpressionType.NotEqual:
                    case ExpressionType.LessThan:
                    case ExpressionType.GreaterThan:
                    case ExpressionType.LessThanOrEqual:
                    case ExpressionType.GreaterThanOrEqual:
                        returnType = translator.TypeSystem.Boolean;
                    break;
                }

                return new JSBinaryOperatorExpression(
                    GetOperator(Operation), 
                    arguments[1], arguments[2], 
                    returnType
                );
            }
예제 #4
0
 public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
     return JSCastExpression.New(
         arguments[1],
         TargetType,
         translator.TypeSystem
     );
 }
예제 #5
0
            public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
                var thisArgument = arguments[1];

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                return new JSDelegateInvocationExpression(
                    JSChangeTypeExpression.New(thisArgument, returnType, translator.TypeSystem), 
                    returnType, arguments.Skip(2).ToArray()
                );
            }
예제 #6
0
            public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                switch (Operation) {
                    case ExpressionType.IsTrue:
                        returnType = translator.TypeSystem.Boolean;
                        break;
                }

                return new JSUnaryOperatorExpression(
                    GetOperator(Operation),
                    arguments[1],
                    returnType
                );
            }
예제 #7
0
 public abstract JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments);
예제 #8
0
            public override JSExpression Translate (ILBlockTranslator translator, JSExpression[] arguments) {
                var thisArgument = FixupThisArgument(arguments[1], translator.TypeSystem);

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                var argumentValues = arguments.Skip(2).ToArray();
                var memberName = MemberName;

                if ((TypeArguments != null) && (TypeArguments.Length > 0)) {
                    memberName += "`" + TypeArguments.Length;
                }

                var thisArgumentKnownType = JSType.ExtractType(thisArgument);
                if (thisArgumentKnownType != null) {
                    var replacement = translator.DoJSILMethodReplacement(
                        thisArgumentKnownType.FullName, memberName, 
                        // FIXME 
                        null,
                        argumentValues,
                        true
                    );
                    if (replacement != null)
                        return replacement;
                }

                return JSInvocationExpression.InvokeMethod(
                    new JSFakeMethod(
                        memberName, returnType, 
                        (from av in argumentValues select av.GetActualType(translator.TypeSystem)).ToArray(),
                        translator.MethodTypes, TypeArguments,
                        escape: true
                    ), thisArgument,
                    arguments.Skip(2).ToArray()
                );
            }
예제 #9
0
            public override JSExpression Translate(ILBlockTranslator translator, JSExpression[] arguments)
            {
                var thisArgument = arguments[1];

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                return JSDotExpression.New(
                    thisArgument,
                    new JSStringIdentifier(MemberName, returnType)
                );
            }
예제 #10
0
            public override JSExpression Translate(ILBlockTranslator translator, JSExpression[] arguments)
            {
                var thisArgument = arguments[1];

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                return JSInvocationExpression.InvokeMethod(
                    new JSStringIdentifier(MemberName, returnType), thisArgument,
                    arguments.Skip(2).ToArray()
                );
            }
예제 #11
0
        internal JSFunctionExpression Create(
            MethodInfo info, MethodDefinition methodDef, MethodReference method, 
            QualifiedMemberIdentifier identifier, ILBlockTranslator translator, 
            IEnumerable<JSVariable> parameters, JSBlockStatement body
        )
        {
            var result = new JSFunctionExpression(
                new JSMethod(method, info),
                translator.Variables,
                parameters,
                body
            );

            var entry = new Entry {
                Identifier = identifier,
                Info = info,
                Reference = method,
                Expression = result,
                Variables = translator.Variables,
                ParameterNames = translator.ParameterNames,
                SpecialIdentifiers = translator.SpecialIdentifiers
            };

            Cache.Add(identifier, entry);
            OptimizationQueue.Add(identifier);

            return result;
        }
예제 #12
0
            public override JSExpression Translate(ILBlockTranslator translator, JSExpression[] arguments)
            {
                var thisArgument = FixupThisArgument(arguments[1], translator.TypeSystem);

                var returnType = ReturnType;
                if (returnType == null)
                    returnType = translator.TypeSystem.Void;

                var argumentValues = arguments.Skip(2).ToArray();

                return JSInvocationExpression.InvokeMethod(
                    new JSFakeMethod(
                        MemberName, returnType,
                        (from av in argumentValues select av.GetActualType(translator.TypeSystem)).ToArray(),
                        translator.MethodTypes, TypeArguments
                    ), thisArgument,
                    arguments.Skip(2).ToArray()
                );
            }
예제 #13
0
        internal JSFunctionExpression Create (
            MethodInfo info, MethodDefinition methodDef, MethodReference method, 
            QualifiedMemberIdentifier identifier, ILBlockTranslator translator, 
            JSVariable[] parameters, JSBlockStatement body
        ) {
            var args = new PopulatedCacheEntryArgs {
                Info = info,
                Method = method,
                Translator = translator,
                Parameters = parameters,
                Body = body,
            };

            return Cache.GetOrCreate(identifier, args, MakePopulatedCacheEntry).Expression;
        }
예제 #14
0
        internal JSFunctionExpression TranslateMethodExpression(DecompilerContext context, MethodReference method, MethodDefinition methodDef)
        {
            var oldMethod = context.CurrentMethod;
            try {
                if (method == null)
                    throw new ArgumentNullException("method");
                if (methodDef == null)
                    throw new ArgumentNullException("methodDef");

                var methodInfo = TypeInfoProvider.GetMemberInformation<JSIL.Internal.MethodInfo>(methodDef);

                var identifier = new QualifiedMemberIdentifier(
                    methodInfo.DeclaringType.Identifier, methodInfo.Identifier
                );
                JSFunctionExpression function = null;

                if (FunctionCache.TryGetExpression(identifier, out function))
                    return function;

                if (methodInfo.IsExternal) {
                    FunctionCache.CreateNull(methodInfo, method, identifier);
                    return null;
                }

                var bodyDef = methodDef;
                if (methodInfo.IsFromProxy && methodInfo.Member.HasBody)
                    bodyDef = methodInfo.Member;

                var pr = new ProgressReporter();

                context.CurrentMethod = methodDef;
                if ((methodDef.Body.Instructions.Count > LargeMethodThreshold) && (this.DecompilingMethod != null))
                    this.DecompilingMethod(method.FullName, pr);

                ILBlock ilb;
                var decompiler = new ILAstBuilder();
                var optimizer = new ILAstOptimizer();

                try {
                    ilb = new ILBlock(decompiler.Build(bodyDef, true));
                    optimizer.Optimize(context, ilb);
                } catch (Exception exception) {
                    if (CouldNotDecompileMethod != null)
                        CouldNotDecompileMethod(bodyDef.FullName, exception);

                    FunctionCache.CreateNull(methodInfo, method, identifier);
                    pr.OnFinished();
                    return null;
                }

                var allVariables = ilb.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
                    .Where(v => v != null && !v.IsParameter).Distinct();

                foreach (var v in allVariables) {
                    if (ILBlockTranslator.IsIgnoredType(v.Type)) {
                        FunctionCache.CreateNull(methodInfo, method, identifier);
                        pr.OnFinished();
                        return null;
                    }
                }

                NameVariables.AssignNamesToVariables(context, decompiler.Parameters, allVariables, ilb);

                var translator = new ILBlockTranslator(
                    this, context, method, methodDef,
                    ilb, decompiler.Parameters, allVariables
                );
                var body = translator.Translate();

                if (body == null) {
                    FunctionCache.CreateNull(methodInfo, method, identifier);
                    pr.OnFinished();
                    return null;
                }

                var parameters = from p in translator.ParameterNames select translator.Variables[p];

                if (method.HasGenericParameters) {
                    var type = new TypeReference("System", "Type", context.CurrentModule.TypeSystem.Object.Module, context.CurrentModule.TypeSystem.Object.Scope);
                    parameters = (from gp in method.GenericParameters select new JSVariable(gp.Name, type, method)).Concat(parameters);
                }

                function = FunctionCache.Create(
                    methodInfo, methodDef, method, identifier,
                    translator, parameters, body
                );

                pr.OnFinished();
                return function;
            } finally {
                context.CurrentMethod = oldMethod;
            }
        }
예제 #15
0
 public override JSExpression Translate(ILBlockTranslator translator, JSExpression[] arguments)
 {
     return translator.JSIL.Cast(
         arguments[1],
         TargetType
     );
 }