Пример #1
0
        private JSExpression ComputeAddress(
            JSExpression pointer, JSExpression offsetInElements, JSExpression offsetInBytes,
            out TypeReference elementType
            )
        {
            var pointerType = pointer.GetActualType(TypeSystem);

            elementType = pointerType.GetElementType();
            var elementSize = WasmUtil.SizeOfType(elementType);

            if (
                (offsetInElements != null) &&
                // I'm so helpful :-)))))
                (offsetInBytes == null)
                )
            {
                offsetInBytes = new JSBinaryOperatorExpression(
                    JSOperator.Multiply,
                    offsetInElements,
                    JSLiteral.New(elementSize),
                    pointerType
                    );
            }

            if (offsetInBytes != null)
            {
                var result = new JSPointerAddExpression(pointer, offsetInBytes, false);
                // Console.WriteLine("Constructing pae {0} from {1} {2} {3}", result, pointer, offsetInElements, offsetInBytes);
                return(result);
            }
            else
            {
                return(pointer);
            }
        }
Пример #2
0
        private void EmitFunctionTable()
        {
            if (MethodTable.Count == 0)
            {
                return;
            }

            Formatter.NewLine();

            Formatter.WriteRaw(";; function table");
            Formatter.NewLine();

            Formatter.WriteRaw("(table ");
            Formatter.Indent();
            Formatter.NewLine();

            foreach (var md in MethodTable)
            {
                var name = WasmUtil.FormatMemberName(md);

                Formatter.ConditionalNewLine();
                Formatter.WriteRaw("${0}", name);
            }

            Formatter.Unindent();
            Formatter.ConditionalNewLine();
            Formatter.WriteRaw(")");
            Formatter.NewLine();
        }
Пример #3
0
        public void VisitNode(JSInvocationExpression ie)
        {
            var jsm = ie.JSMethod;

            if (jsm == null)
            {
                Console.WriteLine("Can't translate non-JSMethod {0}", ie);
                Formatter.WriteSExpr("untranslatable.call");
                return;
            }
            else if (!jsm.Method.IsStatic)
            {
                Console.WriteLine("Can't translate instance call {0}", ie);
                Formatter.WriteSExpr("untranslatable.call");
                return;
            }

            var methodDef  = jsm.Reference.Resolve();
            var memberName = WasmUtil.FormatMemberName(methodDef);

            Formatter.WriteSExpr("call", (_) => {
                _.WriteRaw("${0} ", memberName);
                EmitArgumentList(_, ie.Arguments, false);
            });
        }
Пример #4
0
        public void EmitMethodDefinition(DecompilerContext context, MethodReference methodRef, MethodDefinition method, IAstEmitter astEmitter, bool stubbed, JSRawOutputIdentifier dollar, MethodInfo methodInfo = null)
        {
            // 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);

            var sExport = "Wasm.Module.ExportAttribute";

            methodInfo = methodInfo ?? Translator.TypeInfoProvider.GetMethod(methodRef);

            if (methodInfo != null && methodInfo.Metadata.HasAttribute(sExport))
            {
                var exportName = method.Name;
                var ap         = methodInfo.Metadata.GetAttributeParameters(sExport);
                if ((ap.Count == 1) && (ap[0].Value is string))
                {
                    exportName = (string)ap[0].Value;
                }

                Switch(PrecedingType.Export);

                Formatter.WriteRaw("(export \"{0}\" ${1})", exportName, name);
                Formatter.ConditionalNewLine();
            }
        }
Пример #5
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)
                );
        }
Пример #6
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)
                );
        }
Пример #7
0
 public void VisitNode(JSVariable variable)
 {
     Formatter.WriteSExpr(
         "get_local",
         (_) =>
         _.WriteRaw("${0}", WasmUtil.EscapeIdentifier(variable.Name))
         );
 }
Пример #8
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
                );
        }
Пример #9
0
        private void Assign(JSExpression target, JSExpression value)
        {
            var leftVar   = target as JSVariable;
            var leftField = target as JSFieldAccess;
            var leftProp  = target as JSPropertyAccess;

            if (leftVar != null)
            {
                Formatter.WriteSExpr(
                    "set_local",
                    (_) => {
                    _.WriteRaw("${0} ", WasmUtil.EscapeIdentifier(leftVar.Name));
                    Visit(value);
                },
                    lineBreakAfter: true
                    );
            }
            else if (leftField != null)
            {
                Formatter.WriteRaw(
                    "(call $__set_{0} ",
                    EscapedName(leftField)
                    );

                if (!leftField.Field.Field.IsStatic)
                {
                    Visit(leftField.Target);
                    Formatter.WriteRaw(" ");
                }

                Visit(value);
                Formatter.WriteRaw(")");
                Formatter.NewLine();
            }
            else if (leftProp != null)
            {
                var method     = leftProp.OriginalMethod;
                var memberName = WasmUtil.FormatMemberName(method.Reference.Resolve());

                Formatter.WriteSExpr(
                    "call",
                    (_) => {
                    _.WriteRaw("${0} ", memberName);
                    Visit(value);
                },
                    lineBreakAfter: true
                    );
            }
            else
            {
                Console.WriteLine("Invalid assignment target {0} {1}", target.GetType().Name, target);
                return;
            }
        }
Пример #10
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);
        }
Пример #11
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);
            }
                );
        }
Пример #12
0
        public void VisitNode(JSPropertyAccess pa)
        {
            if (pa.IsWrite)
            {
                throw new Exception("Unhandled property write: " + pa);
            }

            var method     = pa.OriginalMethod;
            var memberName = WasmUtil.FormatMemberName(method.Reference.Resolve());

            Formatter.WriteSExpr("call", (_) => {
                _.WriteRaw("${0}", memberName);
            });
        }
Пример #13
0
        private void Assign(JSExpression target, JSExpression value)
        {
            var leftVar   = target as JSVariable;
            var leftField = target as JSFieldAccess;
            var leftProp  = target as JSPropertyAccess;

            if (leftVar != null)
            {
                Formatter.WriteSExpr(
                    "setlocal",
                    (_) => {
                    _.WriteRaw("${0} ", WasmUtil.EscapeIdentifier(leftVar.Name));
                    Visit(value);
                },
                    lineBreakAfter: true
                    );
            }
            else if (leftField != null)
            {
                Formatter.WriteSExpr(
                    // what?????
                    "store_global",
                    (_) => {
                    _.WriteRaw("${0} ", EscapedName(leftField));
                    Visit(value);
                },
                    lineBreakAfter: true
                    );
            }
            else if (leftProp != null)
            {
                var method     = leftProp.OriginalMethod;
                var memberName = WasmUtil.FormatMemberName(method.Reference.Resolve());

                Formatter.WriteSExpr(
                    "call",
                    (_) => {
                    _.WriteRaw("${0} ", memberName);
                    Visit(value);
                },
                    lineBreakAfter: true
                    );
            }
            else
            {
                Console.WriteLine("Invalid assignment target {0}", target);
                return;
            }
        }
Пример #14
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();
        }
Пример #15
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);
            }
                );
        }
Пример #16
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));
        }
Пример #17
0
        private void EmitLabelledBlock(string label, Action <JavascriptFormatter> writeBody)
        {
            if (label == null)
            {
                writeBody(Formatter);
                return;
            }

            Formatter.WriteSExpr(
                "label", (_) => {
                _.WriteRaw("${0} ", WasmUtil.EscapeIdentifier(label));
                _.NewLine();
                writeBody(_);
            },
                lineBreakAfter: true
                );
        }
Пример #18
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;
 }
Пример #19
0
        private void VisitFakeMethod(JSInvocationExpression ie, JSFakeMethod fakeMethod)
        {
            if (TypeUtil.IsDelegateType(fakeMethod.ReturnType) && fakeMethod.Name == "New")
            {
                var type = (JSType)ie.Arguments[0];
                // FIXME: What the heck is in arg1????
                var method = UnwrapDeferred <JSMethod>(ie.Arguments[2]);

                var methodDef  = method.Reference.Resolve();
                var memberName = WasmUtil.FormatMemberName(methodDef);

                Formatter.WriteRaw("(i32.const {0} (; {1} ;))", AssemblyEmitter.GetFunctionIndex(methodDef), methodDef.FullName);
                return;
            }

            Console.WriteLine("Can't translate fake method {0}", ie);
            Formatter.WriteSExpr("untranslatable.call");
            return;
        }
Пример #20
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;
        }
Пример #21
0
        public int?GetFieldOffset(FieldDefinition fd)
        {
            var key = fd.FullName;

            FieldTableEntry result;

            if (!FieldTable.TryGetValue(key, out result))
            {
                var size = WasmUtil.SizeOfType(fd.FieldType);

                // HACK HACK HACK
                int offset = fd.IsStatic
                    ? (int)ReserveHeapSpace(size)
                    : WasmUtil.OffsetOfField(fd);

                result = new FieldTableEntry(offset, fd);
                FieldTable.Add(key, result);
            }

            return(result.Offset);
        }
Пример #22
0
 public GetMemory(
     TypeReference type, bool isAligned,
     JSExpression addressInBytes
     ) : base(
         string.Format(
             "load{0}{1}.{2}",
             TypeUtil.IsSigned(type).GetValueOrDefault()
             ? "s"
             : "u",
             isAligned
             ? ""
             // WTF???
             : ".1",
             WasmUtil.PickMemoryTypeKeyword(type)
             ),
         addressInBytes
         )
 {
     Type      = type;
     IsAligned = isAligned;
 }
Пример #23
0
        public void VisitNode(JSInvocationExpression ie)
        {
            var jsm = ie.JSMethod;

            if (jsm == null)
            {
                var d = ie.Method as JSDotExpression;
                if (d != null)
                {
                    var m = d.Member as JSFakeMethod;
                    if (m != null)
                    {
                        VisitFakeMethod(ie, m);
                        return;
                    }
                }

                Console.WriteLine("Can't translate non-JSMethod {0}", ie);
                Formatter.WriteSExpr("untranslatable.call");
                return;
            }
            else if (!jsm.Method.IsStatic)
            {
                Console.WriteLine("Can't translate instance call {0}", ie);
                Formatter.WriteSExpr("untranslatable.call");
                return;
            }

            var methodDef  = jsm.Reference.Resolve();
            var memberName = WasmUtil.FormatMemberName(methodDef);

            var manyArgs = ie.Arguments.Count > 2;

            Formatter.WriteSExpr("call", (_) => {
                _.WriteRaw("${0} ", memberName);
                EmitArgumentList(_, ie.Arguments, manyArgs);
            }, lineBreakInside: manyArgs);
        }
Пример #24
0
        public SetMemory(
            TypeReference type, bool isAligned,
            JSExpression addressInBytes, JSExpression value
            ) : base(
                string.Format(
                    "store{0}{1}.{2}",
                    TypeUtil.IsSigned(type).GetValueOrDefault()
                    ? "s"
                    : "u",
                    isAligned
                    ? ""
                    // WTF???
                    : ".1",
                    WasmUtil.PickMemoryTypeKeyword(type)
                    ),
                addressInBytes, value
                )
        {
            Type      = type;
            IsAligned = isAligned;

            LineBreakInside = true;
            LineBreakAfter  = true;
        }
Пример #25
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();
        }
Пример #26
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();
        }
Пример #27
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
                );
        }
Пример #28
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
                );
        }
Пример #29
0
        public void VisitNode(JSSizeOfExpression sizeofExp)
        {
            var type = sizeofExp.Type.Type;

            Formatter.WriteRaw("(i32.const (; sizeof {0} ;) {1})", type, WasmUtil.SizeOfType(type));
        }
Пример #30
0
 private string EscapedName(FieldInfo fi)
 {
     return(WasmUtil.FormatMemberName(fi.Member));
 }