Beispiel #1
0
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            var leftType     = boe.Left.GetActualType(TypeSystem);
            var leftIsEnum   = IsEnumOrNullableEnum(leftType);
            var rightType    = boe.Right.GetActualType(TypeSystem);
            var rightIsEnum  = IsEnumOrNullableEnum(rightType);
            var resultType   = boe.GetActualType(TypeSystem);
            var resultIsEnum = IsEnumOrNullableEnum(resultType);

            if ((leftIsEnum || rightIsEnum) && LogicalOperators.Contains(boe.Operator))
            {
                if (leftIsEnum)
                {
                    var cast = JSInvocationExpression.InvokeStatic(
                        JS.Number(TypeSystem.Int32), new[] { boe.Left }, true
                        );

                    boe.ReplaceChild(boe.Left, cast);
                }

                if (rightIsEnum)
                {
                    var cast = JSInvocationExpression.InvokeStatic(
                        JS.Number(TypeSystem.Int32), new[] { boe.Right }, true
                        );

                    boe.ReplaceChild(boe.Right, cast);
                }
            }

            VisitChildren(boe);
        }
Beispiel #2
0
 public JSInvocationExpression GetTypeFromAssembly(JSExpression assembly, JSExpression typeName, JSExpression throwOnFail)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("GetTypeFromAssembly", TypeSystem.SystemType()),
                new[] { assembly, typeName, new JSNullLiteral(TypeSystem.Object), throwOnFail }, true
                ));
 }
Beispiel #3
0
 public JSInvocationExpression GetTypeOf(JSExpression expression)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("GetType", TypeSystem.SystemType()),
                new[] { expression }, true
                ));
 }
Beispiel #4
0
 public JSInvocationExpression GetTypeFromAssembly(JSExpression assembly, JSExpression typeName, JSExpression throwOnFail)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("GetTypeFromAssembly", new TypeReference("System", "Type", TypeSystem.Object.Module, TypeSystem.Object.Scope)),
                new[] { assembly, typeName, new JSNullLiteral(TypeSystem.Object), throwOnFail }, true
                ));
 }
Beispiel #5
0
 public JSInvocationExpression CreateInstanceOfType(TypeReference type)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot(new JSFakeMethod("CreateInstanceOfType", type, new[] { TypeSystem.Object }, MethodTypes)),
                new[] { new JSTypeOfExpression(type) }
                ));
 }
Beispiel #6
0
 public JSInvocationExpression CheckType(JSExpression expression, TypeReference targetType)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("CheckType", TypeSystem.Boolean),
                new[] { expression, new JSTypeOfExpression(targetType) }, true
                ));
 }
Beispiel #7
0
 public JSInvocationExpression ThrowNullReferenceException()
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot(new JSFakeMethod("ThrowNullReferenceException", TypeSystem.Void, new TypeReference[0], MethodTypes)),
                new JSExpression[0]
                ));
 }
Beispiel #8
0
 public JSInvocationExpression StructEquals(JSExpression left, JSExpression right)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("StructEquals", TypeSystem.Boolean),
                new[] { left, right }, true
                ));
 }
Beispiel #9
0
 public JSInvocationExpression GetTypeOf(JSExpression expression)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("GetType", new TypeReference("System", "Type", TypeSystem.Object.Module, TypeSystem.Object.Scope)),
                new[] { expression }, true
                ));
 }
Beispiel #10
0
 public JSInvocationExpression Coalesce(JSExpression left, JSExpression right, TypeReference expectedType)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("Coalesce", expectedType),
                new[] { left, right }, true
                ));
 }
Beispiel #11
0
 public JSInvocationExpression FreezeImmutableObject(JSExpression @object)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot(new JSFakeMethod("FreezeImmutableObject", TypeSystem.Void, new[] { TypeSystem.Object }, MethodTypes)),
                new[] { @object }
                ));
 }
Beispiel #12
0
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            var exType = uoe.Expression.GetActualType(TypeSystem);
            var opType = uoe.ActualType;

            if (IsLongOrULong(exType) && IsLongOrULong(opType)) //exType == TypeSystem.Int64 && opType == TypeSystem.Int64)
            {
                string verb;
                switch (uoe.Operator.Token)
                {
                case "-":
                    verb = "op_UnaryNegation";
                    break;

                case "~":
                    verb = "op_OnesComplement";
                    break;

                default:
                    throw new NotSupportedException();
                }

                var method      = new JSFakeMethod(verb, TypeSystem.Int64, new[] { TypeSystem.Int64 }, MethodTypeFactory);
                var replacement = JSInvocationExpression.InvokeStatic(exType, method, new[] { uoe.Expression }, true);
                ParentNode.ReplaceChild(uoe, replacement);
                VisitReplacement(replacement);
                return;
            }

            VisitChildren(uoe);
        }
Beispiel #13
0
 public JSExpression Cast(JSExpression expression, TypeReference targetType)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("Cast", targetType),
                new[] { expression, new JSTypeOfExpression(targetType) }, true
                ));
 }
Beispiel #14
0
 public JSInvocationExpression ShallowCopy(JSExpression array, JSExpression initializer, TypeReference arrayType)
 {
     return(JSInvocationExpression.InvokeStatic(
                new JSDotExpression(
                    Dot("Array", TypeSystem.Object),
                    new JSFakeMethod("ShallowCopy", TypeSystem.Void, new[] { arrayType, arrayType }, MethodTypes)
                    ), new[] { array, initializer }
                ));
 }
Beispiel #15
0
 public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod)
 {
     return(JSInvocationExpression.InvokeStatic(
                new JSDotExpression(
                    new JSType(delegateType),
                    new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)
                    ), new [] { thisReference, targetMethod },
                true
                ));
 }
        public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod)
        {
            var targetDotExpression = targetMethod as JSDotExpressionBase;
            var jsMethod            = targetDotExpression != null ? targetDotExpression.Member as JSMethod : null;

            JSExpression[] invocationExpressionArguments;

            if (jsMethod == null)
            {
                // Not sure if it is possible.
                invocationExpressionArguments = new[] { thisReference, targetMethod };
            }
            else
            {
                var jsMethodAccess = targetMethod as JSMethodAccess;
                var arguments      = jsMethod == null
                    ? null
                    : jsMethod.Reference.Parameters.Select(
                    (parameter, index) => (JSExpression) new JSRawOutputIdentifier(parameter.ParameterType, "arguments[{0}]", index))
                                     .ToArray();

                bool isFromDelegate = jsMethod.Reference.Name == "Invoke" && TypeUtil.IsDelegateType(jsMethod.Reference.DeclaringType);

                JSExpression methodInvocation;
                if (isFromDelegate)
                {
                    methodInvocation = targetMethod;
                }
                else if (jsMethod.Method.IsStatic)
                {
                    methodInvocation = new JSDeferredExpression(JSInvocationExpression.InvokeStatic(jsMethod.Reference.DeclaringType, jsMethod, arguments));
                }
                else if (jsMethodAccess == null || jsMethodAccess.IsVirtual)
                {
                    methodInvocation = new JSDeferredExpression(JSInvocationExpression.InvokeMethod(jsMethod.Reference.DeclaringType, jsMethod, thisReference, arguments));
                }
                else
                {
                    methodInvocation = new JSDeferredExpression(JSInvocationExpression.InvokeBaseMethod(jsMethod.Reference.DeclaringType, jsMethod, thisReference, arguments));
                }

                invocationExpressionArguments = new[] {
                    thisReference,
                    methodInvocation,
                    new JSDeferredExpression(new JSMethodOfExpression(jsMethod.Reference, jsMethod.Method, jsMethod.MethodTypes, jsMethod.GenericArguments))
                };
            }

            return(JSInvocationExpression.InvokeStatic(
                       new JSDotExpression(
                           new JSType(delegateType),
                           new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)),
                       invocationExpressionArguments,
                       true));
        }
Beispiel #17
0
        public JSInvocationExpression ValueOfNullable(JSExpression nullableExpression)
        {
            var valueType = nullableExpression.GetActualType(TypeSystem);

            valueType = TypeUtil.StripNullable(valueType);

            return(JSInvocationExpression.InvokeStatic(
                       Dot("ValueOfNullable", valueType),
                       new[] { nullableExpression }, true
                       ));
        }
Beispiel #18
0
        public JSExpression ValueOfNullableOrDefault(JSExpression nullableExpression, JSExpression defaultValue)
        {
            var valueType = nullableExpression.GetActualType(TypeSystem);

            valueType = TypeUtil.StripNullable(valueType);

            return(JSInvocationExpression.InvokeStatic(
                       Dot("Nullable_ValueOrDefault", valueType),
                       new[] { nullableExpression, defaultValue }, true
                       ));
        }
Beispiel #19
0
        public JSInvocationExpression NewArray(TypeReference elementType, JSExpression sizeOrArrayInitializer)
        {
            var arrayType = new ArrayType(elementType);

            return(JSInvocationExpression.InvokeStatic(
                       new JSDotExpression(
                           Dot("Array", TypeSystem.Object),
                           new JSFakeMethod("New", arrayType, new[] { arrayType }, MethodTypes)
                           ), new [] { new JSType(elementType), sizeOrArrayInitializer },
                       true
                       ));
        }
Beispiel #20
0
        public JSInvocationExpression StackAlloc(JSExpression sizeInBytes, TypeReference pointerType)
        {
            if (!pointerType.IsPointer)
            {
                throw new InvalidOperationException("Type being stack-allocated must be a pointer");
            }

            return(JSInvocationExpression.InvokeStatic(
                       Dot(new JSFakeMethod("StackAlloc", pointerType, new[] { TypeSystem.Int32, TypeSystem.Object }, MethodTypes)),
                       new[] { sizeInBytes, new JSType(TypeUtil.GetElementType(pointerType, true)) }
                       ));
        }
Beispiel #21
0
 public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod, JSMethod method)
 {
     return(JSInvocationExpression.InvokeStatic(
                new JSDotExpression(
                    new JSType(delegateType),
                    new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)
                    ),
                method == null ? new [] { thisReference, targetMethod } : new [] {
         thisReference,
         targetMethod,
         new JSDefferedExpression(new JSMethodOfExpression(method.Reference, method.Method, method.MethodTypes, method.GenericArguments)),
     },
                true
                ));
 }
Beispiel #22
0
        public JSInvocationExpression GetLongLiteralExpression(long number, bool unsigned = false)
        {
            var  type = unsigned ? TypeSystem.UInt64 : TypeSystem.Int64;
            uint a    = (uint)(number & 0xffffff);
            uint b    = (uint)((number >> 24) & 0xffffff);
            uint c    = (uint)((number >> 48) & 0xffff);

            return(JSInvocationExpression
                   .InvokeStatic(
                       new JSType(type),
                       new JSFakeMethod("Create", type, new[] { TypeSystem.UInt32, TypeSystem.UInt32, TypeSystem.UInt32 }, MethodTypeFactory),
                       new JSExpression[] {
                new JSIntegerLiteral((long)a, typeof(uint)),
                new JSIntegerLiteral((long)b, typeof(uint)),
                new JSIntegerLiteral((long)c, typeof(uint))
            }));
        }
Beispiel #23
0
        public JSInvocationExpression NewMultidimensionalArray(TypeReference elementType, JSExpression[] dimensions, JSExpression initializer = null)
        {
            var arrayType = new ArrayType(elementType, dimensions.Length);
            var arguments = new JSExpression[] { new JSType(elementType) }.Concat(dimensions);

            if (initializer != null)
            {
                arguments = arguments.Concat(new[] { initializer });
            }

            return(JSInvocationExpression.InvokeStatic(
                       new JSDotExpression(
                           Dot("MultidimensionalArray", TypeSystem.Object),
                           new JSFakeMethod("New", arrayType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)
                           ), arguments.ToArray(), true
                       ));
        }
Beispiel #24
0
        public void VisitNode(JSIndexerExpression ie)
        {
            var indexType = ie.Index.GetActualType(TypeSystem);

            if (
                !TypeUtil.IsIntegral(indexType) &&
                IsEnumOrNullableEnum(indexType)
                )
            {
                var cast = JSInvocationExpression.InvokeStatic(
                    JS.Number(TypeSystem.Int32), new[] { ie.Index }, true
                    );

                ie.ReplaceChild(ie.Index, cast);
            }

            VisitChildren(ie);
        }
Beispiel #25
0
        public void VisitNode(JSSwitchStatement ss)
        {
            var conditionType = ss.Condition.GetActualType(TypeSystem);

            if (
                !TypeUtil.IsIntegral(conditionType) &&
                IsEnumOrNullableEnum(conditionType)
                )
            {
                var cast = JSInvocationExpression.InvokeStatic(
                    JS.Number(TypeSystem.Int32), new[] { ss.Condition }, true
                    );

                ss.ReplaceChild(ss.Condition, cast);
            }

            VisitChildren(ss);
        }
Beispiel #26
0
        public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod)
        {
            var targetDotExpression = targetMethod as JSDotExpressionBase;
            var jsMethod            = targetDotExpression != null ? targetDotExpression.Member as JSMethod : null;

            JSExpression[] invocationExpressionArguments;

            if (jsMethod == null)
            {
                // Not sure if it is possible.
                invocationExpressionArguments = new[] { thisReference, targetMethod };
            }
            else
            {
                var useRuntimeDispatch = jsMethod.Method != null &&
                                         jsMethod.Method.Metadata.HasAttribute("JSIL.Meta.JSRuntimeDispatch");
                var jsMethodAccess = targetMethod as JSMethodAccess;

                invocationExpressionArguments = new[]
                {
                    thisReference,
                    useRuntimeDispatch ? targetMethod : new JSNullLiteral(TypeSystem.Object),
                    new JSMethodPointerInfoExpression(
                        jsMethod.Reference,
                        jsMethod.Method,
                        jsMethod.MethodTypes,
                        jsMethodAccess != null && jsMethodAccess.IsVirtual,
                        jsMethod.GenericArguments),
                };
            }

            return(JSInvocationExpression.InvokeStatic(
                       new JSDotExpression(
                           new JSType(delegateType),
                           new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)),
                       invocationExpressionArguments,
                       true));
        }
Beispiel #27
0
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            var type   = uoe.Expression.GetActualType(TypeSystem);
            var isEnum = IsEnumOrNullableEnum(type);

            if (isEnum)
            {
                var cast = JSInvocationExpression.InvokeStatic(
                    JS.Number(TypeSystem.Int32), new[] { uoe.Expression }, true
                    );

                if (LogicalOperators.Contains(uoe.Operator))
                {
                    uoe.ReplaceChild(uoe.Expression, cast);
                }
                else if (uoe.Operator == JSOperator.Negation)
                {
                    uoe.ReplaceChild(uoe.Expression, cast);
                }
            }

            VisitChildren(uoe);
        }
Beispiel #28
0
        public JSInvocationExpression CreateNamedFunction(TypeReference resultType, JSExpression name, JSExpression argumentNames, JSExpression body, JSExpression closure = null)
        {
            var nae = argumentNames as JSNewArrayExpression;

            if (nae != null)
            {
                argumentNames = nae.SizeOrArrayInitializer;
            }

            // FIXME: We should do a cast of the result to ensure it's actually the requested result type instead of just a raw JS function
            return(JSInvocationExpression.InvokeStatic(
                       Dot(
                           new JSFakeMethod(
                               "CreateNamedFunction", resultType,
                               new[] {
                TypeSystem.String, new ArrayType(TypeSystem.String), TypeSystem.String, TypeSystem.Object
            }, MethodTypes
                               )
                           ),
                       new[] {
                name, argumentNames, body, closure
            }
                       ));
        }
Beispiel #29
0
 protected JSInvocationExpression CastToChar(JSExpression integerExpression)
 {
     return(JSInvocationExpression.InvokeStatic(
                JS.fromCharCode, new[] { integerExpression }, true
                ));
 }
Beispiel #30
0
        private void EmitCctors()
        {
            // HACK
            var identifier = (MemberIdentifier)Activator.CreateInstance(
                typeof(MemberIdentifier),
                System.Reflection.BindingFlags.Instance |
                System.Reflection.BindingFlags.NonPublic,
                null,
                new object[] {
                true, MemberIdentifier.MemberType.Method,
                ".cctor", EntryPointAstEmitter.TypeSystem.Void,
                null, 0
            },
                null
                );

            // Find types we emitted that have static constructors
            var cctors = (
                from t in TypesToStaticInitialize
                let ti = Translator.TypeInfoProvider.GetExisting(t)
                         where ti.Members.ContainsKey(identifier)
                         let mi = ti.Members[identifier]
                                  select(MethodInfo) mi
                ).ToList();

            if (cctors.Count == 0)
            {
                return;
            }

            NeedStaticInit = true;
            Formatter.NewLine();

            Formatter.WriteRaw(";; Compiler-generated static constructor dispatcher");
            Formatter.NewLine();
            // If we found any, we need to generate a special function that invokes all the cctors
            Formatter.WriteRaw("(func $__static_init (block ");
            Formatter.Indent();
            Formatter.NewLine();

            // FIXME: Walk cctor dependencies and invoke in correct order
            foreach (var cctor in cctors)
            {
                // Synthesize a regular static method call
                var jsm = new JSMethod(
                    cctor.Member, cctor, Translator.FunctionCache.MethodTypes
                    );
                var call = JSInvocationExpression.InvokeStatic(jsm, new JSExpression[0], false);

                // HACK
                EntryPointAstEmitter.Emit(call);
                Formatter.ConditionalNewLine();
            }

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

            Formatter.WriteRaw("(export \"__static_init\" $__static_init)");
            Formatter.NewLine();
        }