예제 #1
0
        private void EmitFieldOrConstant(
            DecompilerContext context, IAstEmitter astEmitter,
            FieldDefinition field, JSRawOutputIdentifier dollar,
            JSExpression defaultValue, bool isConstant
            )
        {
            var fieldInfo = _TypeInfoProvider.GetMemberInformation <Internal.FieldInfo>(field);

            if ((fieldInfo == null) || fieldInfo.IsIgnored)
            {
                return;
            }

            Formatter.NewLine();

            dollar.WriteTo(Formatter);
            Formatter.Dot();
            Formatter.Identifier(
                isConstant
                    ? "Constant"
                    : "Field", EscapingMode.None
                );
            Formatter.LPar();

            Formatter.MemberDescriptor(
                field.IsPublic, fieldInfo.IsStatic,
                isReadonly: field.IsInitOnly,
                offset: field.DeclaringType.IsExplicitLayout
                    ? (int?)field.Offset
                    : null
                );

            Formatter.Comma();

            var fieldName = Util.EscapeIdentifier(fieldInfo.Name, EscapingMode.MemberIdentifier);

            Formatter.Value(fieldName);

            Formatter.Comma();

            Formatter.TypeReference(fieldInfo.FieldType, astEmitter.ReferenceContext);

            if (defaultValue != null)
            {
                Formatter.Comma();
                astEmitter.Emit(defaultValue);
            }

            Formatter.RPar();

            EmitCustomAttributes(context, field.DeclaringType, field, astEmitter);

            Formatter.Semicolon();
        }
예제 #2
0
        public void EmitFunctionBody(IAstEmitter astEmitter, MethodDefinition method, JSFunctionExpression function)
        {
            astEmitter.ReferenceContext.Push();
            astEmitter.ReferenceContext.EnclosingMethod = method;

            try {
                astEmitter.Emit(function);
            } catch (Exception exc) {
                throw new Exception("Error occurred while generating javascript for method '" + method.FullName + "'.", exc);
            } finally {
                astEmitter.ReferenceContext.Pop();
            }

            EmitSemicolon();
            EmitSpacer();
        }
예제 #3
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();
        }
예제 #4
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();
        }
예제 #5
0
        public void EmitFunctionBody (IAstEmitter astEmitter, MethodDefinition method, JSFunctionExpression function) {
            astEmitter.ReferenceContext.Push();
            astEmitter.ReferenceContext.EnclosingMethod = method;

            try {
                astEmitter.Emit(function);
            } catch (Exception exc) {
                throw new Exception("Error occurred while generating javascript for method '" + method.FullName + "'.", exc);
            } finally {
                astEmitter.ReferenceContext.Pop();
            }

            EmitSemicolon();
            EmitSpacer();
        }
예제 #6
0
        private void EmitFieldOrConstant (
            DecompilerContext context, IAstEmitter astEmitter, 
            FieldDefinition field, JSRawOutputIdentifier dollar, 
            JSExpression defaultValue, bool isConstant
        ) {
            var fieldInfo = TypeInfo.GetMemberInformation<Internal.FieldInfo>(field);
            if ((fieldInfo == null) || fieldInfo.IsIgnored)
                return;

            Formatter.NewLine();

            dollar.WriteTo(Formatter);
            Formatter.Dot();
            Formatter.Identifier(
                isConstant 
                    ? "Constant"
                    : "Field", EscapingMode.None
            );
            Formatter.LPar();

            Formatter.MemberDescriptor(
                field.IsPublic, fieldInfo.IsStatic,
                isReadonly: field.IsInitOnly,
                offset: field.DeclaringType.IsExplicitLayout 
                    ? (int?)field.Offset 
                    : null
            );

            Formatter.Comma();

            var fieldName = Util.EscapeIdentifier(fieldInfo.Name, EscapingMode.MemberIdentifier);

            Formatter.Value(fieldName);

            Formatter.Comma();

            Formatter.TypeReference(fieldInfo.FieldType, astEmitter.ReferenceContext);

            if (defaultValue != null) {
                Formatter.Comma();
                astEmitter.Emit(defaultValue);
            }

            Formatter.RPar();

            EmitCustomAttributes(context, field.DeclaringType, field, astEmitter);

            Formatter.Semicolon();
        }
예제 #7
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();
        }