PickTypeKeyword() 공개 정적인 메소드

public static PickTypeKeyword ( TypeReference type ) : string
type Mono.Cecil.TypeReference
리턴 string
예제 #1
0
        public void VisitNode(JSLiteral literal)
        {
            var literalType = literal.GetActualType(TypeSystem);
            var typeToken   = WasmUtil.PickTypeKeyword(literalType);

            if (typeToken == null)
            {
                Console.WriteLine("AstEmitter Unhandled literal type {0}", literalType.FullName);

                Formatter.WriteSExpr("untranslatable.literal");
            }

            dynamic literalValue;

            if (literal is JSDefaultValueLiteral)
            {
                literalValue = 0;
            }
            else
            {
                literalValue = (dynamic)literal.Literal;
                if (literalValue is bool)
                {
                    literalValue = (literalValue ? 1 : 0);
                }
            }

            Formatter.WriteSExpr(
                "const." + typeToken,
                // HACK
                (_) => Formatter.Value(literalValue)
                );
        }
예제 #2
0
        private void VisitLiteral(JSLiteral literal, TypeReference forcedType = null)
        {
            var literalType = forcedType ?? literal.GetActualType(TypeSystem);

            if ((literal is JSNullLiteral) && (literalType.FullName == "System.Object"))
            {
                // HACK: ILSpy screws up the type inference...
                VisitStringLiteral(null);
                return;
            }

            var typeToken = WasmUtil.PickTypeKeyword(literalType);

            if (typeToken == null)
            {
                Console.WriteLine("AstEmitter Unhandled literal type {0}", literalType.FullName);

                Formatter.WriteSExpr("untranslatable.literal");
            }

            if (literalType.FullName == "System.String")
            {
                if ((literal is JSDefaultValueLiteral) || (literal is JSNullLiteral))
                {
                    VisitStringLiteral(null);
                }
                else
                {
                    var literalStr = (string)literal.Literal;
                    VisitStringLiteral(literalStr);
                }
                return;
            }

            dynamic literalValue;

            if (literal is JSDefaultValueLiteral)
            {
                literalValue = 0;
            }
            else
            {
                literalValue = (dynamic)literal.Literal;
                if (literalValue is bool)
                {
                    literalValue = (literalValue ? 1 : 0);
                }
                else if (literalValue is char)
                {
                    literalValue = (int)(char)literalValue;
                }
            }

            Formatter.WriteSExpr(
                typeToken + ".const",
                // HACK
                (_) => Formatter.Value(literalValue)
                );
        }
예제 #3
0
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            var boeType   = boe.GetActualType(TypeSystem);
            var typeToken = WasmUtil.PickTypeKeyword(boeType);

            if (typeToken == null)
            {
                Console.WriteLine("Unhandled binary operator type {0}", boeType);
                return;
            }

            if (boe.Operator == JSOperator.Assignment)
            {
                Assign(boe.Left, boe.Right);
                return;
            }

            string keyword;

            if (!OperatorTable.TryGetValue(boe.Operator, out keyword))
            {
                Console.WriteLine("Unimplemented operator {0}", boe.Operator);
                return;
            }

            var leftType  = boe.Left.GetActualType(TypeSystem);
            var rightType = boe.Right.GetActualType(TypeSystem);
            var leftSign  = TypeUtil.IsSigned(leftType);

            // HACK: Emit the argument type since we're comparing it
            if (boe.Operator is JSComparisonOperator)
            {
                typeToken = WasmUtil.PickTypeKeyword(leftType);
            }

            var signSuffix = "";

            if (leftSign.HasValue && TypeUtil.IsIntegral(leftType))
            {
                signSuffix = leftSign.Value
                    ? "s"
                    : "u";
            }

            var actualKeyword = string.Format(
                keyword + "." + typeToken,
                signSuffix
                );

            Formatter.WriteSExpr(
                actualKeyword,
                (_) => EmitArgumentList(_, new[] { boe.Left, boe.Right }, true),
                true, false
                );
        }
예제 #4
0
        public void EmitField(DecompilerContext context, IAstEmitter astEmitter, FieldDefinition field, JSRawOutputIdentifier dollar, JSExpression defaultValue)
        {
            var fieldInfo   = Translator.TypeInfoProvider.GetField(field);
            var typeKeyword = WasmUtil.PickTypeKeyword(fieldInfo.FieldType);

            // Unhandled type
            if (typeKeyword == null)
            {
                return;
            }

            GetFieldOffset(field);
        }
예제 #5
0
        public void VisitNode(JSIntegerToFloatExpression itfe)
        {
            var type              = itfe.GetActualType(TypeSystem);
            var typeToken         = WasmUtil.PickTypeKeyword(type);
            var originalType      = itfe.Expression.GetActualType(TypeSystem);
            var originalTypeToken = WasmUtil.PickTypeKeyword(originalType);

            Formatter.WriteSExpr(
                "converts." + originalTypeToken + "." + typeToken, (_) => {
                Visit(itfe.Expression);
            }
                );
        }
예제 #6
0
        public void EmitField(DecompilerContext context, IAstEmitter astEmitter, FieldDefinition field, JSRawOutputIdentifier dollar, JSExpression defaultValue)
        {
            var fieldInfo   = Translator.TypeInfoProvider.GetField(field);
            var typeKeyword = WasmUtil.PickTypeKeyword(fieldInfo.FieldType);

            // Unhandled type
            if (typeKeyword == null)
            {
                return;
            }

            Switch(PrecedingType.Global);

            Formatter.WriteRaw("(global ${0} {1})", WasmUtil.EscapeIdentifier(fieldInfo.Name), typeKeyword);
            Formatter.ConditionalNewLine();
        }
예제 #7
0
        public void VisitNode(JSIntegerToFloatExpression itfe)
        {
            var type              = itfe.GetActualType(TypeSystem);
            var typeToken         = WasmUtil.PickTypeKeyword(type);
            var originalType      = itfe.Expression.GetActualType(TypeSystem);
            var originalTypeToken = WasmUtil.PickTypeKeyword(originalType);

            Formatter.WriteSExpr(
                string.Format(
                    "{0}.convert_s/{1}",
                    typeToken,
                    originalTypeToken
                    ), (_) => {
                Visit(itfe.Expression);
            }
                );
        }
예제 #8
0
        public static Tuple <bool, string> ShouldSkipMember(MemberReference member)
        {
            var fr = member as FieldReference;
            var mr = member as MethodReference;

            if (fr != null)
            {
                return(Skip(WasmUtil.PickTypeKeyword(fr.FieldType) == null, "Unsupported field type"));
            }

            if (mr != null)
            {
                return(Skip(WasmUtil.PickTypeKeyword(mr.ReturnType) == null, "Unsupported return type"));
            }

            return(Skip(false));
        }
예제 #9
0
 public GetMemory(
     TypeReference type, bool isAligned,
     JSExpression addressInBytes
     ) : base(
         string.Format(
             "{0}.load{1}{2}",
             WasmUtil.PickTypeKeyword(type),
             WasmUtil.PickMemoryTypeSuffix(type, false),
             isAligned
             ? ""
             : "/1"
             ),
         addressInBytes
         )
 {
     Type      = type;
     IsAligned = isAligned;
 }
예제 #10
0
        public SetMemory(
            TypeReference type, bool isAligned,
            JSExpression addressInBytes, JSExpression value
            ) : base(
                string.Format(
                    "{0}.store{1}{2}",
                    WasmUtil.PickTypeKeyword(type),
                    WasmUtil.PickMemoryTypeSuffix(type, true),
                    isAligned
                    ? ""
                    : "/1"
                    ),
                addressInBytes, value
                )
        {
            Type      = type;
            IsAligned = isAligned;

            LineBreakInside = true;
            LineBreakAfter  = true;
        }
예제 #11
0
        public void EmitFunctionBody(IAstEmitter astEmitter, MethodDefinition method, JSFunctionExpression function)
        {
            // Skip Main() and emit it at the footer
            if (Assembly.EntryPoint == method)
            {
                // HACK: Store this so we can use it to emit the entry point's body later
                EntryPointAstEmitter = astEmitter;
                return;
            }

            var name = WasmUtil.FormatMemberName(method);

            Switch(PrecedingType.Function, true);

            Formatter.WriteRaw("(func ${0}", name);
            Formatter.Indent();
            Formatter.NewLine();

            int v = 0;

            foreach (var kvp in function.AllVariables)
            {
                var variable = kvp.Value;

                var type = WasmUtil.PickTypeKeyword(variable.IdentifierType);
                if (type != null)
                {
                    Formatter.WriteRaw(
                        "({0} ${1} {2}) ",
                        variable.IsParameter
                            ? "param"
                            : "local",
                        WasmUtil.EscapeIdentifier(kvp.Key), type
                        );

                    if (v++ >= 3)
                    {
                        v = 0;
                        Formatter.NewLine();
                    }
                }
            }

            if (function.LabelGroupCount > 0)
            {
                Formatter.NewLine();
            }
            for (var i = 0; i < function.LabelGroupCount; i++)
            {
                Formatter.WriteRaw("(local $currentLabel_{0} i32) ", i);
            }

            var returnType = WasmUtil.PickTypeKeyword(method.ReturnType);

            if (returnType != "void")
            {
                Formatter.NewLine();
                Formatter.WriteRaw("(result {0})", returnType);
            }

            Formatter.ConditionalNewLine();
            Formatter.NewLine();

            astEmitter.Emit(function.Body);

            Formatter.ConditionalNewLine();
            Formatter.Unindent();
            Formatter.WriteRaw(")");

            Formatter.NewLine();
        }
예제 #12
0
        private void EmitFieldIntrinsics(int heapSize)
        {
            // FIXME: Gross
            var tis = (ITypeInfoSource)Translator.TypeInfoProvider;

            Formatter.WriteRaw(";; Compiler-generated field accessors");
            Formatter.NewLine();

            foreach (var kvp in FieldTable.OrderBy(kvp => kvp.Value.Offset))
            {
                var fd         = kvp.Value.Field;
                var fi         = (FieldInfo)tis.Get(fd);
                var name       = WasmUtil.FormatMemberName(fi.Member);
                var typeSystem = fd.FieldType.Module.TypeSystem;

                // HACK
                var baseAddressParam = new JSVariable("address", typeSystem.Int32, null);
                // HACK
                var valueParam = new JSVariable("value", fd.FieldType, null);

                JSExpression address;
                if (fd.IsStatic)
                {
                    address = JSLiteral.New(kvp.Value.Offset + heapSize);
                }
                else
                {
                    address = new JSBinaryOperatorExpression(
                        JSOperator.Add,
                        baseAddressParam,
                        JSLiteral.New(kvp.Value.Offset),
                        typeSystem.Int32
                        );
                }

                Formatter.ConditionalNewLine();
                Formatter.WriteRaw(
                    "(func $__get_{0} (result {1}){2}(return ",
                    name,
                    WasmUtil.PickTypeKeyword(fd.FieldType),
                    fd.IsStatic
                        ? " "
                        : " (param $address i32) "
                    );

                var gm = new GetMemory(
                    fd.FieldType, /* FIXME: Align addresses */ false,
                    address
                    );

                // HACK
                EntryPointAstEmitter.Emit(gm);

                Formatter.WriteRaw(") )");

                if (fd.IsInitOnly)
                {
                    continue;
                }

                Formatter.NewLine();
                Formatter.WriteRaw(
                    "(func $__set_{0}{2}(param $value {1}) ",
                    name,
                    WasmUtil.PickTypeKeyword(fd.FieldType),
                    fd.IsStatic
                        ? " "
                        : " (param $address i32) "
                    );
                Formatter.Indent();
                Formatter.NewLine();
                var sm = new SetMemory(
                    fd.FieldType, /* FIXME: Align addresses */ false,
                    address, valueParam
                    );

                // HACK
                EntryPointAstEmitter.Emit(sm);

                Formatter.Unindent();
                Formatter.ConditionalNewLine();
                Formatter.WriteRaw(")");
            }

            Formatter.NewLine();
            Formatter.NewLine();
        }
예제 #13
0
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            var boeType   = boe.GetActualType(TypeSystem);
            var typeToken = WasmUtil.PickTypeKeyword(boeType);

            if (boe.Operator == JSOperator.Assignment)
            {
                Assign(boe.Left, boe.Right);
                return;
            }

            string keyword;

            if (!OperatorTable.TryGetValue(boe.Operator, out keyword))
            {
                Console.WriteLine("Unimplemented operator {0}", boe.Operator);
                return;
            }

            var leftType  = boe.Left.GetActualType(TypeSystem);
            var rightType = boe.Right.GetActualType(TypeSystem);
            var leftSign  = TypeUtil.IsSigned(leftType);

            // HACK: Emit the argument type since we're comparing it
            if (boe.Operator is JSComparisonOperator)
            {
                typeToken = WasmUtil.PickTypeKeyword(leftType);
            }

            var signSuffix = "";

            if (
                (leftSign.HasValue && TypeUtil.IsIntegral(leftType)) ||
                // HACK
                (leftType.FullName == "System.Char")
                )
            {
                signSuffix = leftSign.GetValueOrDefault(true)
                    ? "_s"
                    : "_u";
            }
            else if (
                TypeUtil.IsPointer(leftType) ||
                TypeUtil.IsPointer(rightType)
                )
            {
                signSuffix = "_u";
            }

            var actualKeyword = string.Format(
                typeToken + "." + keyword,
                signSuffix
                );

            // HACK: wasm i64 shift takes i64 shift amount
            var right = boe.Right;

            if (
                (boe.Operator == JSOperator.ShiftLeft) ||
                (boe.Operator == JSOperator.ShiftRight)
                )
            {
                right = JSChangeTypeExpression.New(right, leftType, TypeSystem);
            }

            if (typeToken == null)
            {
                Console.WriteLine("Unhandled binary operator type {0} ({1})", boeType, boe);
                return;
            }

            Formatter.WriteSExpr(
                actualKeyword,
                (_) => EmitArgumentList(_, new[] { boe.Left, right }, true),
                true, false
                );
        }
예제 #14
0
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            var resultType = uoe.GetActualType(TypeSystem);
            var typeToken  = WasmUtil.PickTypeKeyword(resultType);

            if (typeToken == null)
            {
                Console.WriteLine("Unhandled unary operator type {0}", resultType);
                return;
            }

            if (uoe.Operator == JSOperator.LogicalNot)
            {
                Formatter.WriteRaw("({0}.xor ", typeToken);
                Visit(uoe.Expression);
                Formatter.WriteRaw(" ({0}.const 1))", typeToken);
                return;
            }
            else if (uoe.Operator == JSOperator.Negation)
            {
                Formatter.WriteRaw("({0}.sub ({0}.const 0) ", typeToken);
                Visit(uoe.Expression);
                Formatter.WriteRaw(")", typeToken);
                return;
            }

            string keyword;

            if (!OperatorTable.TryGetValue(uoe.Operator, out keyword))
            {
                Console.WriteLine("Unimplemented operator {0}", uoe.Operator);
                return;
            }

            var operandType = uoe.Expression.GetActualType(TypeSystem);
            var sign        = TypeUtil.IsSigned(operandType);

            var signSuffix = "";

            if (
                (sign.HasValue && TypeUtil.IsIntegral(operandType)) ||
                // HACK
                (operandType.FullName == "System.Char")
                )
            {
                signSuffix = sign.GetValueOrDefault(true)
                    ? "_s"
                    : "_u";
            }

            var actualKeyword = string.Format(
                typeToken + "." + keyword,
                signSuffix
                );

            Formatter.WriteSExpr(
                actualKeyword,
                (_) => EmitArgumentList(_, new[] { uoe.Expression }, true),
                true, false
                );
        }
예제 #15
0
        void EmitCast(JSExpression value, TypeReference toType)
        {
            var fromType = value.GetActualType(TypeSystem);

            var fromIntegral = TypeUtil.IsIntegral(fromType);
            var toIntegral   = TypeUtil.IsIntegral(toType);

            var fromSize = WasmUtil.SizeOfType(fromType);
            var toSize   = WasmUtil.SizeOfType(toType);

            var fromSign = TypeUtil.IsSigned(fromType);
            var toSign   = TypeUtil.IsSigned(toType);

            var signSuffix = fromSign.GetValueOrDefault(toSign.GetValueOrDefault(true))
                ? "s"
                : "u";

            if (fromIntegral && toIntegral)
            {
                if ((toSize == 4) && (fromSize == 8))
                {
                    Formatter.WriteRaw("(i32.wrap/i64 ");
                    Visit(value);
                    Formatter.WriteRaw(")");
                    return;
                }
                else if ((toSize == 8) && (fromSize == 4))
                {
                    Formatter.WriteRaw("(i64.extend_{0}/i32 ", signSuffix);
                    Visit(value);
                    Formatter.WriteRaw(")");
                    return;
                }
                else if ((toSize == fromSize) && (toSign != fromSign))
                {
                    Visit(value);
                    return;
                }
                else if ((toSize == 2) || (toSize == 1))
                {
                    var mask        = (1 << (8 * toSize)) - 1;
                    var synthesized = new JSBinaryOperatorExpression(
                        JSOperator.BitwiseAnd,
                        value, JSLiteral.New(mask),
                        toType
                        );
                    Visit(synthesized);
                    return;
                }
                else if (toType.FullName == "JSIL.Types.NativeInt")
                {
                    Visit(value);
                    return;
                }
            }
            else if (toIntegral)
            {
                Formatter.WriteRaw(
                    "({0}.trunc_{1}/{2} ",
                    WasmUtil.PickTypeKeyword(toType),
                    signSuffix,
                    WasmUtil.PickTypeKeyword(fromType)
                    );
                Visit(value);
                Formatter.WriteRaw(")");
                return;
            }

            Console.Error.WriteLine("unimplemented cast {0} -> {1}", fromType, toType);
            Visit(value);
        }