Exemplo n.º 1
0
        protected JSExpression BindGenericMethodArguments(JSExpression function, MethodBase mi, MethodBase callingScope, Type typeScope, JSExpression thisScope)
        {
            if (mi.IsGenericMethod || (mi.IsStatic && mi.DeclaringType.IsGenericType))
            {
                // For static methods on generic classes, the type arguments are passed to
                // the method at the call site rather than wired through the generic class type.

                // This is the same behavior as generic static methods (on nongeneric class), so both are handled here.

                // Of course, this also extends to generic static methods on generic classes.

                var classGenArgs  = (mi.IsStatic && mi.DeclaringType.IsGenericType) ? mi.DeclaringType.GetGenericArguments() : new Type[0];
                var methodGenArgs = mi.IsGenericMethod ? mi.GetGenericArguments() : new Type[0];

                return(new JSCallExpression
                {
                    Function = function,
                    Arguments = Enumerable
                                .Concat(
                        classGenArgs,
                        methodGenArgs)
                                .Select(t => GetTypeIdentifier(t, methodScope: callingScope, typeScope: typeScope, thisScope: thisScope))
                                .ToList()
                });
            }
            else
            {
                return(function);
            }
        }
Exemplo n.º 2
0
 public JSInvocationExpression CheckType(JSExpression expression, TypeReference targetType)
 {
     return JSInvocationExpression.InvokeStatic(
         Dot("CheckType", TypeSystem.Boolean),
         new[] { expression, new JSTypeOfExpression(targetType) }, true
     );
 }
Exemplo n.º 3
0
        protected void EliminateVariable (JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) {
            {
                var replacer = new VariableEliminator(
                    variable,
                    JSChangeTypeExpression.New(replaceWith, variable.GetActualType(TypeSystem), TypeSystem)
                );
                replacer.Visit(context);
            }

            {
                var replacer = new VariableEliminator(variable, replaceWith);
                var assignments = (from a in FirstPass.Assignments where 
                                       variable.Equals(a.NewValue) ||
                                       a.NewValue.SelfAndChildrenRecursive.Any(variable.Equals)
                                       select a).ToArray();

                foreach (var a in assignments) {
                    if (!variable.Equals(a.NewValue))
                        replacer.Visit(a.NewValue);
                }
            }

            Variables.Remove(variable.Identifier);
            FunctionSource.InvalidateFirstPass(method);
        }
Exemplo n.º 4
0
        protected JSExpression FixupThisArgument (JSExpression thisArgument, TypeSystem typeSystem) {
            var expectedType = thisArgument.GetActualType(typeSystem);
            if (expectedType.FullName == "System.Type")
                return new JSPublicInterfaceOfExpression(thisArgument);

            return thisArgument;
        }
Exemplo n.º 5
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
                ));
 }
Exemplo n.º 6
0
 public JSInvocationExpression GetTypeOf(JSExpression expression)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("GetType", new TypeReference("System", "Type", TypeSystem.Object.Module, TypeSystem.Object.Scope)),
                new[] { expression }, true
                ));
 }
Exemplo n.º 7
0
 public JSInvocationExpression Coalesce(JSExpression left, JSExpression right, TypeReference expectedType)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("Coalesce", expectedType),
                new[] { left, right }, true
                ));
 }
Exemplo n.º 8
0
 public JSExpression Cast(JSExpression expression, TypeReference targetType)
 {
     return JSInvocationExpression.InvokeStatic(
         Dot("Cast", targetType),
         new[] { expression, new JSTypeOfExpression(targetType) }, true
     );
 }
Exemplo n.º 9
0
        protected bool MatchesConstructedReference (JSExpression lhs, JSVariable rhs) {
            var jsv = lhs as JSVariable;
            if ((jsv != null) && (jsv.Identifier == rhs.Identifier))
                return true;

            return false;
        }
Exemplo n.º 10
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
                ));
 }
Exemplo n.º 11
0
 public JSInvocationExpression Coalesce(JSExpression left, JSExpression right, TypeReference expectedType)
 {
     return JSInvocationExpression.InvokeStatic(
         Dot("Coalesce", expectedType),
         new[] { left, right }, true
     );
 }
Exemplo n.º 12
0
        public JSNewArrayElementReference NewElementReference(JSExpression target, JSExpression index)
        {
            var           arrayType = TypeUtil.DereferenceType(target.GetActualType(TypeSystem));
            TypeReference resultType;

            if (PackedArrayUtil.IsPackedArrayType(arrayType))
            {
                resultType = new ByReferenceType(
                    PackedArrayUtil.GetElementType(arrayType)
                    );
            }
            else if (TypeUtil.IsArray(arrayType))
            {
                resultType = new ByReferenceType(
                    TypeUtil.GetElementType(arrayType, true)
                    );
            }
            else
            {
                throw new ArgumentException("Cannot create a reference to an element of a value of type '" + arrayType.FullName + "'", target.ToString());
            }

            if (PackedArrayUtil.IsPackedArrayType(target.GetActualType(TypeSystem)))
            {
                return(new JSNewPackedArrayElementReference(resultType, target, index));
            }
            else
            {
                return(new JSNewArrayElementReference(resultType, target, index));
            }
        }
Exemplo n.º 13
0
        public static bool ExtractOffsetFromPointerExpression(JSExpression pointer, TypeSystem typeSystem, out JSExpression newPointer, out JSExpression offset)
        {
            offset = null;
            newPointer = pointer;

            var boe = pointer as JSBinaryOperatorExpression;
            if (boe == null)
                return false;

            var leftType = boe.Left.GetActualType(typeSystem);
            var rightType = boe.Right.GetActualType(typeSystem);
            var resultType = boe.GetActualType(typeSystem);

            if (!resultType.IsPointer)
                return false;

            if (!TypeUtil.IsIntegral(rightType))
                return false;

            if (boe.Operator != JSOperator.Add)
                return false;

            newPointer = boe.Left;
            offset = boe.Right;
            return true;
        }
Exemplo n.º 14
0
 public JSInvocationExpression GetTypeOf(JSExpression expression)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("GetType", TypeSystem.SystemType()),
                new[] { expression }, true
                ));
 }
Exemplo n.º 15
0
        public static void CheckInvocationSafety(MethodInfo method, JSExpression[] argumentValues, TypeSystem typeSystem)
        {
            if (method.Metadata.HasAttribute("JSIL.Meta.JSAllowPackedArrayArgumentsAttribute"))
                return;

            TypeReference temp;
            string[] argumentNames = GetPackedArrayArgumentNames(method, out temp);

            for (var i = 0; i < method.Parameters.Length; i++) {
                if (i >= argumentValues.Length)
                    continue;

                var valueType = argumentValues[i].GetActualType(typeSystem);

                if (!IsPackedArrayType(valueType)) {
                    if ((argumentNames != null) && argumentNames.Contains(method.Parameters[i].Name))
                        throw new ArgumentException(
                            "Invalid attempt to pass a normal array as parameter '" + method.Parameters[i].Name + "' to method '" + method.Name + "'. " +
                            "This parameter must be a packed array."
                        );
                } else {
                    if ((argumentNames == null) || !argumentNames.Contains(method.Parameters[i].Name))
                        throw new ArgumentException(
                            "Invalid attempt to pass a packed array as parameter '" + method.Parameters[i].Name + "' to method '" + method.Name + "'. " +
                            "If this is intentional, annotate the method with the JSPackedArrayArguments attribute."
                        );
                }
            }
        }
Exemplo n.º 16
0
        protected bool IsImmutable (JSExpression target) {
            while (target is JSReferenceExpression)
                target = ((JSReferenceExpression)target).Referent;

            var fieldAccess = target as JSFieldAccess;
            if (fieldAccess != null) {
                return fieldAccess.Field.Field.Metadata.HasAttribute("JSIL.Meta.JSImmutable");
            }

            var dot = target as JSDotExpressionBase;
            if (dot != null) {
                if (IsImmutable(dot.Target))
                    return true;
                else if (IsImmutable(dot.Member))
                    return true;
            }

            var indexer = target as JSIndexerExpression;
            if (indexer != null) {
                if (IsImmutable(indexer.Target))
                    return true;
            }

            return false;
        }
Exemplo n.º 17
0
        protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method)
        {
            {
                var replacer = new VariableEliminator(
                    variable,
                    JSChangeTypeExpression.New(replaceWith, variable.GetActualType(TypeSystem), TypeSystem)
                    );
                replacer.Visit(context);
            }

            {
                var replacer    = new VariableEliminator(variable, replaceWith);
                var assignments = (from a in FirstPass.Assignments where
                                   variable.Equals(a.NewValue) ||
                                   a.NewValue.SelfAndChildrenRecursive.Any(variable.Equals)
                                   select a).ToArray();

                foreach (var a in assignments)
                {
                    if (!variable.Equals(a.NewValue))
                    {
                        replacer.Visit(a.NewValue);
                    }
                }
            }

            Variables.Remove(variable.Identifier);
            FunctionSource.InvalidateFirstPass(method);
        }
Exemplo n.º 18
0
        public JSExpression Cast(JSExpression expression, TypeReference targetType)
        {
            var currentType = ILBlockTranslator.DereferenceType(expression.GetExpectedType(TypeSystem));
            targetType = ILBlockTranslator.DereferenceType(targetType);

            if (targetType.MetadataType == MetadataType.Char) {
                return JSInvocationExpression.InvokeStatic(JS.fromCharCode, new[] { expression }, true);
            } else if (
                (currentType.MetadataType == MetadataType.Char) &&
                ILBlockTranslator.IsIntegral(targetType)
            ) {
                return JSInvocationExpression.InvokeMethod(JS.charCodeAt, expression, new[] { JSLiteral.New(0) }, true);
            } else if (
                ILBlockTranslator.IsEnum(currentType) &&
                ILBlockTranslator.IsIntegral(targetType)
            ) {
                return new JSDotExpression(
                    expression, new JSStringIdentifier("value", targetType)
                );
            } else {
                return JSInvocationExpression.InvokeStatic(
                    Dot("Cast", targetType),
                    new [] { expression, new JSType(targetType) }, true
                );
            }
        }
Exemplo n.º 19
0
 public JSInvocationExpression FreezeImmutableObject(JSExpression @object)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot(new JSFakeMethod("FreezeImmutableObject", TypeSystem.Void, new[] { TypeSystem.Object }, MethodTypes)),
                new[] { @object }
                ));
 }
Exemplo n.º 20
0
        public static JSExpression FilterInvocationResult(
            MethodReference methodReference, MethodInfo method, 
            JSExpression result, 
            ITypeInfoSource typeInfo, TypeSystem typeSystem
        )
        {
            if (method == null)
                return result;

            var resultType = result.GetActualType(typeSystem);
            var resultIsPackedArray = PackedArrayUtil.IsPackedArrayType(resultType);
            var returnValueAttribute = method.Metadata.GetAttribute("JSIL.Meta.JSPackedArrayReturnValueAttribute");

            if (returnValueAttribute != null) {
                if (TypeUtil.IsOpenType(resultType)) {
                    // FIXME: We need to restrict substitution to when the result type is a generic parameter owned by the invocation...
                    resultType = JSExpression.SubstituteTypeArgs(typeInfo, resultType, methodReference);
                }

                if (!resultIsPackedArray)
                    return JSChangeTypeExpression.New(result, PackedArrayUtil.MakePackedArrayType(resultType, returnValueAttribute.Entries.First().Type), typeSystem);
            }

            return result;
        }
Exemplo n.º 21
0
 public JSInvocationExpression StructEquals(JSExpression left, JSExpression right)
 {
     return(JSInvocationExpression.InvokeStatic(
                Dot("StructEquals", TypeSystem.Boolean),
                new[] { left, right }, true
                ));
 }
        private JSExpression Hoist (JSExpression expression, TypeReference type, List<JSExpression> commaElements) {
            if (expression is JSVariable)
                return null;
            else if (expression is JSLiteral)
                return null;

            var thisBoe = expression as JSBinaryOperatorExpression;
            if ((thisBoe != null) &&
                (thisBoe.Operator == JSOperator.Assignment) &&
                (thisBoe.Left is JSVariable)
            ) {
                // If the value is (x = y), insert 'x = y' and then set the value to 'x'
                commaElements.Add(thisBoe);
                return thisBoe.Left;
            } else {
                var tempVar = new JSRawOutputIdentifier(
                    type, "$temp{0:X2}", Function.TemporaryVariableCount++
                );

                commaElements.Add(new JSBinaryOperatorExpression(
                    JSOperator.Assignment, tempVar, expression, type
                ));

                return tempVar;
            }
        }
Exemplo n.º 23
0
 protected JSInvocationExpression CastToInteger(JSExpression booleanExpression)
 {
     return JSInvocationExpression.InvokeMethod(
         JS.Number(TypeSystem.SByte),
         booleanExpression, null, true
     );
 }
Exemplo n.º 24
0
        private JSExpression Hoist(JSExpression expression, TypeReference type, List <JSExpression> commaElements)
        {
            if (expression is JSVariable)
            {
                return(null);
            }
            else if (expression is JSLiteral)
            {
                return(null);
            }

            var thisBoe = expression as JSBinaryOperatorExpression;

            if ((thisBoe != null) &&
                (thisBoe.Operator == JSOperator.Assignment) &&
                (thisBoe.Left is JSVariable)
                )
            {
                // If the value is (x = y), insert 'x = y' and then set the value to 'x'
                commaElements.Add(thisBoe);
                return(thisBoe.Left);
            }
            else
            {
                var tempVar = new JSRawOutputIdentifier(
                    type, "$temp{0:X2}", Function.TemporaryVariableCount++
                    );

                commaElements.Add(new JSBinaryOperatorExpression(
                                      JSOperator.Assignment, tempVar, expression, type
                                      ));

                return(tempVar);
            }
        }
Exemplo n.º 25
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
     );
 }
        protected bool IsEffectivelyConstant(JSExpression expression)
        {
            if (expression.IsConstant)
                return true;

            var invocation = expression as JSInvocationExpression;
            FunctionAnalysis2ndPass secondPass = null;
            if ((invocation != null) && (invocation.JSMethod != null)) {
                secondPass = FunctionSource.GetSecondPass(invocation.JSMethod);

                if ((secondPass != null) && secondPass.IsPure)
                    return true;

                var methodName = invocation.JSMethod.Method.Name;
                if ((methodName == "IDisposable.Dispose") || (methodName == "Dispose")) {
                    var thisType = invocation.ThisReference.GetActualType(TypeSystem);

                    if (thisType != null) {
                        var typeInfo = TypeInfo.GetExisting(thisType);

                        if ((typeInfo != null) && typeInfo.Metadata.HasAttribute("JSIL.Meta.JSPureDispose"))
                            return true;
                    }
                }
            }

            return false;
        }
Exemplo n.º 27
0
        protected bool IsCopyNeededForAssignmentTarget(JSExpression target)
        {
            if (!OptimizeCopies)
            {
                return(true);
            }

            if (IsImmutable(target))
            {
                return(false);
            }

            while (target is JSReferenceExpression)
            {
                target = ((JSReferenceExpression)target).Referent;
            }

            var variable = target as JSVariable;

            if (variable != null)
            {
                return(SecondPass.ModifiedVariables.Contains(variable.Name));
            }

            return(true);
        }
Exemplo n.º 28
0
 private bool CanSkipUsageVeto(JSExpression replacement)
 {
     return
         ((replacement is JSLiteral) &&
          // Usage count veto is important for struct literals since they can be mutated
          //  after-the-fact
          !TypeUtil.IsStruct(replacement.GetActualType(TypeSystem)));
 }
Exemplo n.º 29
0
 public BlockTranslator(Context context, CilAssembly assembly, CilType type, CilMethod method, JSExpression this_)
     : base(context)
 {
     this.type     = type;
     this.assembly = assembly;
     this.method   = method;
     this.this_    = this_;
 }
Exemplo n.º 30
0
        public JSNewBoxedVariable NewReference(JSExpression initialValue)
        {
            var valueType = initialValue.GetActualType(TypeSystem);

            return(new JSNewBoxedVariable(
                       initialValue, valueType
                       ));
        }
Exemplo n.º 31
0
 public JSExpression NullableHasValue(JSExpression nullableExpression)
 {
     return(new JSBinaryOperatorExpression(
                JSOperator.NotEqual,
                nullableExpression, new JSNullLiteral(TypeSystem.Object),
                TypeSystem.Boolean
                ));
 }
Exemplo n.º 32
0
        protected JSExpression FixupThisArgument(JSExpression thisArgument, TypeSystem typeSystem)
        {
            var expectedType = thisArgument.GetActualType(typeSystem);
            if (expectedType.FullName == "System.Type")
                return new JSPublicInterfaceOfExpression(thisArgument);

            return thisArgument;
        }
Exemplo n.º 33
0
 public AssertReturn(JSExpression expected, string exportedFunctionName, JSExpression[] arguments)
     : base(
         "assert_return",
         (new[] { expected }).Concat(arguments).ToArray()
         )
 {
     ExportedFunctionName = exportedFunctionName;
 }
Exemplo n.º 34
0
        public JSNewExpression NewMemberReference(JSExpression target, JSLiteral member)
        {
            var resultType = new ByReferenceType(member.GetActualType(TypeSystem));

            return(new JSNewExpression(
                       Dot("MemberReference", resultType),
                       null, null, target, member
                       ));
        }
Exemplo n.º 35
0
        public void VisitNode(JSVariable variable)
        {
            if (variable.IsThis)
            {
                if (ThisReplacementStack.Count > 0)
                {
                    var thisRef = ThisReplacementStack.Peek();
                    if (thisRef != null)
                    {
                        Visit(thisRef);
                    }

                    return;
                }
                else
                {
                    Output.WriteRaw("this");
                }
            }
            else
            {
                Output.Identifier(variable.Identifier);
            }

            // Don't emit .value when initializing a reference in a declaration.
            var boe = ParentNode as JSBinaryOperatorExpression;

            if (
                (boe != null) &&
                (boe.Left == variable) &&
                (Stack.Skip(2).FirstOrDefault() is JSVariableDeclarationStatement)
                )
            {
                return;
            }

            if (variable.IsReference)
            {
                if (variable.IsThis)
                {
                    if (JSExpression.DeReferenceType(variable.Type).IsValueType)
                    {
                        return;
                    }
                    else
                    {
                        throw new InvalidOperationException(String.Format(
                                                                "The this-reference '{0}' was a reference to a non-value type: {1}",
                                                                variable, variable.Type
                                                                ));
                    }
                }

                Output.Dot();
                Output.Identifier("value");
            }
        }
Exemplo n.º 36
0
        public JSExpression ValueOfNullable(JSExpression nullableExpression)
        {
            if (nullableExpression is JSValueOfNullableExpression)
            {
                return(nullableExpression);
            }

            return(new JSValueOfNullableExpression(nullableExpression));
        }
Exemplo n.º 37
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 }
                ));
 }
Exemplo n.º 38
0
        public JSNewExpression NewReference(JSExpression initialValue)
        {
            var resultType = new ByReferenceType(initialValue.GetActualType(TypeSystem));

            return(new JSNewExpression(
                       Dot("Variable", resultType),
                       null, null, initialValue
                       ));
        }
Exemplo n.º 39
0
        /// <summary>
        /// Writes an interface member reference to the output.
        /// </summary>
        public void WriteInterfaceMemberToOutput(
            JavascriptFormatter output, Compiler.Extensibility.IAstEmitter astEmitter,
            JSFunctionExpression enclosingFunction,
            JSMethod jsMethod, JSExpression method,
            TypeReferenceContext referenceContext
            )
        {
            int index;

            CachedInterfaceMemberRecord record;

            GenericParameter[] rewrittenGenericParameters = null;
            if (LocalCachingEnabled && PreferLocalCacheForGenericInterfaceMethodSignatures)
            {
                record = new CachedInterfaceMemberRecord(jsMethod.Reference.DeclaringType, jsMethod.Identifier);
            }
            else
            {
                var rewritten = GenericTypesRewriter.Normalized(jsMethod.Reference.DeclaringType);
                record = new CachedInterfaceMemberRecord(rewritten.CacheRecord, jsMethod.Identifier,
                                                         rewritten.RewritedGenericParameters.Length);
                rewrittenGenericParameters = rewritten.RewritedGenericParameters;
            }

            if (enclosingFunction.Method != null && enclosingFunction.Method.Method != null)
            {
                var      functionIdentifier = enclosingFunction.Method.Method.Identifier;
                CacheSet localSignatureSet;

                if (LocalCachedSets.TryGetValue(functionIdentifier, out localSignatureSet))
                {
                    if (localSignatureSet.InterfaceMembers.TryGetValue(record, out index))
                    {
                        output.WriteRaw("$im{0:X2}", index);

                        return;
                    }
                }
            }

            if (!Global.InterfaceMembers.TryGetValue(record, out index))
            {
                output.Identifier(jsMethod.Reference.DeclaringType, referenceContext, false);
                output.Dot();
                astEmitter.Emit(method);
            }
            else
            {
                output.WriteRaw("$IM{0:X2}", index);
                output.LPar();
                if (rewrittenGenericParameters != null)
                {
                    output.CommaSeparatedList(rewrittenGenericParameters, referenceContext);
                }
                output.RPar();
            }
        }
Exemplo n.º 40
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
                ));
 }
Exemplo n.º 41
0
        public static bool ExtractOffsetFromPointerExpression(JSExpression pointer, TypeSystem typeSystem, out JSExpression newPointer, out JSExpression offset)
        {
            pointer = JSPointerExpressionUtil.UnwrapExpression(pointer);

            offset     = null;
            newPointer = pointer;

            var boe = pointer as JSBinaryOperatorExpression;

            if (boe == null)
            {
                return(false);
            }

            if (boe.Right.IsNull)
            {
                return(false);
            }

            var right = JSPointerExpressionUtil.UnwrapExpression(boe.Right);

            var rightType  = right.GetActualType(typeSystem);
            var resultType = boe.GetActualType(typeSystem);

            if (!resultType.IsPointer)
            {
                return(false);
            }

            if (
                !TypeUtil.IsIntegral(rightType) &&
                // Adding pointers together shouldn't be valid but ILSpy generates it. Pfft.
                !TypeUtil.IsPointer(rightType)
                )
            {
                return(false);
            }

            if (boe.Operator == JSOperator.Subtract)
            {
                newPointer = boe.Left;
                offset     = new JSUnaryOperatorExpression(JSOperator.Negation, right, rightType);
                return(true);
            }
            else if (boe.Operator == JSOperator.Add)
            {
                newPointer = boe.Left;
                offset     = right;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 42
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 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));
        }
Exemplo n.º 43
0
        private static JSExpression Mul(TypeSystem typeSystem, JSExpression lhs, JSExpression rhs)
        {
            long iLhs, iRhs;

            if (ExtractLiteral(lhs, out iLhs) && ExtractLiteral(rhs, out iRhs))
            {
                return(JSLiteral.New((int)(iLhs * iRhs)));
            }

            return(new JSBinaryOperatorExpression(JSOperator.Multiply, lhs, rhs, typeSystem.Int32));
        }
        protected bool MatchesConstructedReference(JSExpression lhs, JSVariable rhs)
        {
            var jsv = lhs as JSVariable;

            if ((jsv != null) && (jsv.Identifier == rhs.Identifier))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 45
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
                       ));
        }
Exemplo n.º 46
0
        public static JSExpression MakeReadVersion (JSExpression e) {
            var fa = e as JSFieldAccess;
            var pa = e as JSPropertyAccess;
            if ((fa != null) && fa.IsWrite)
                return new JSFieldAccess(fa.ThisReference, fa.Field, false);
            else if ((pa != null) && pa.IsWrite)
                return new JSPropertyAccess(
                    pa.ThisReference, pa.Property, false, pa.TypeQualified, pa.OriginalType, pa.OriginalMethod, pa.IsVirtualCall
                );

            return e;
        }
Exemplo n.º 47
0
        public static JSExpression MakeLhsForAssignment (JSExpression rhs) {
            var fa = rhs as JSFieldAccess;
            var pa = rhs as JSPropertyAccess;
            if ((fa != null) && (fa.IsWrite == false))
                return new JSFieldAccess(fa.ThisReference, fa.Field, true);
            else if ((pa != null) && (pa.IsWrite == false))
                return new JSPropertyAccess(
                    pa.ThisReference, pa.Property, true, pa.TypeQualified, pa.OriginalType, pa.OriginalMethod, pa.IsVirtualCall
                );

            return rhs;
        }
Exemplo n.º 48
0
        protected bool IsCopyNeededForAssignmentTarget (JSExpression target) {
            if (!OptimizeCopies)
                return true;

            if (IsImmutable(target))
                return false;

            var variable = target as JSVariable;
            if (variable != null)
                return SecondPass.ModifiedVariables.Contains(variable.Name);

            return true;
        }
Exemplo n.º 49
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();
        }
        public void VisitNode (JSPropertySetterInvocation psi) {
            if (ParentNode is JSExpressionStatement) {
                VisitChildren(psi);
                return;
            }

            var thisReference = psi.Invocation.ThisReference;
            var valueType = psi.GetActualType(TypeSystem);
            var thisType = thisReference.GetActualType(TypeSystem);

            JSExpression tempThis;
            JSExpression[] tempArguments = new JSExpression[psi.Invocation.Arguments.Count];
            var commaElements = new List<JSExpression>();

            tempThis = Hoist(thisReference, thisType, commaElements);

            for (var i = 0; i < tempArguments.Length; i++) {
                var arg = psi.Invocation.Arguments[i];
                var argType = arg.GetActualType(TypeSystem);

                tempArguments[i] = Hoist(arg, argType, commaElements);
            }

            var resultInvocation = psi.Invocation;

            if ((tempThis != null) || tempArguments.Any(ta => ta != null)) {
                resultInvocation = psi.Invocation.FilterArguments(
                    (i, a) => {
                        if ((i >= 0) && (tempArguments[i] != null))
                            return tempArguments[i];
                        else if ((i == -1) && (tempThis != null))
                            return tempThis;
                        else
                            return a;
                    }
                );
            }

            commaElements.Add(resultInvocation);

            if (tempArguments.Last() != null)
                commaElements.Add(tempArguments.Last());
            else
                commaElements.Add(psi.Value);

            var replacement = new JSCommaExpression(commaElements.ToArray());

            ParentNode.ReplaceChild(psi, replacement);
            VisitReplacement(replacement);
        }
Exemplo n.º 51
0
        private JSBinaryOperatorExpression MakeUnaryMutation (
            JSExpression expressionToMutate, JSBinaryOperator mutationOperator,
            TypeReference type
        ) {
            var newValue = new JSBinaryOperatorExpression(
                mutationOperator, expressionToMutate, JSLiteral.New(1),
                type
            );
            var assignment = new JSBinaryOperatorExpression(
                JSOperator.Assignment,
                MakeLhsForAssignment(expressionToMutate), newValue, type
            );

            return assignment;
        }
Exemplo n.º 52
0
        protected TypeReference UnwrapType(JSExpression expression)
        {
            var type = expression as JSType;
            if (type != null)
                return type.Type;

            var invocation = expression as JSInvocationExpression;
            if (invocation != null) {
                type = invocation.Arguments.FirstOrDefault() as JSType;
                if (type != null)
                    return type.Type;
            }

            throw new NotImplementedException("Unrecognized type expression");
        }
Exemplo n.º 53
0
        protected bool IsCopyNeededForAssignmentTarget (JSExpression target) {
            target = JSReferenceExpression.Strip(target);

            if (!OptimizeCopies)
                return true;

            if (IsImmutable(target))
                return false;

            var variable = target as JSVariable;
            if (variable != null)
                return SecondPass.IsVariableModified(variable.Name);

            return true;
        }
Exemplo n.º 54
0
 public AbstractSExpression(
     string keyword, TypeReference type, JSExpression[] values,
     bool isConstant = false, bool isConstantIfArgumentsAre = false,
     bool hasGlobalStateDependency = false, 
     bool lineBreakAfter = false, bool lineBreakInside = false
 )
     : base(keyword, values)
 {
     Type = type;
     _IsConstant = isConstant;
     IsConstantIfArgumentsAre = isConstantIfArgumentsAre;
     _HasGlobalStateDependency = hasGlobalStateDependency;
     LineBreakAfter = lineBreakAfter;
     LineBreakInside = lineBreakInside;
 }
Exemplo n.º 55
0
        public static JSExpression FilterInvocationResult(MethodInfo method, JSExpression result, TypeSystem typeSystem)
        {
            if (method == null)
                return result;

            var resultType = result.GetActualType(typeSystem);
            var resultIsPackedArray = PackedArrayUtil.IsPackedArrayType(resultType);
            var returnValueAttribute = method.Metadata.GetAttribute("JSIL.Meta.JSPackedArrayReturnValueAttribute");

            if (returnValueAttribute != null) {
                if (!resultIsPackedArray)
                    return JSChangeTypeExpression.New(result, PackedArrayUtil.MakePackedArrayType(resultType, returnValueAttribute.Entries.First().Type), typeSystem);
            }

            return result;
        }
Exemplo n.º 56
0
        protected DynamicCallSiteInfo(TypeReference targetType, JSExpression[] arguments)
        {
            Arguments = arguments;

            var targetTypeName = targetType.FullName;
            var git = targetType as GenericInstanceType;

            if (targetTypeName.StartsWith("System.Action`")) {
                ReturnType = null;
            } else if (targetTypeName.StartsWith("System.Func`")) {
                ReturnType = git.GenericArguments[git.GenericArguments.Count - 1];
            } else
                throw new NotImplementedException("This type of call site target is not implemented");

            if ((BinderFlags & CSharpBinderFlags.ResultDiscarded) == CSharpBinderFlags.ResultDiscarded)
                ReturnType = null;
        }
Exemplo n.º 57
0
        public static JSBinaryOperatorExpression MakeUnaryMutation (
            JSExpression expressionToMutate, JSBinaryOperator mutationOperator,
            TypeReference type, TypeSystem typeSystem
        ) {
            var newValue = new JSBinaryOperatorExpression(
                mutationOperator, expressionToMutate, JSLiteral.New(1),
                type
            );
            var assignment = new JSBinaryOperatorExpression(
                JSOperator.Assignment,
                MakeLhsForAssignment(expressionToMutate), newValue, type
            );

            assignment = ConvertReadExpressionToWriteExpression(assignment, typeSystem);

            return assignment;
        }
Exemplo n.º 58
0
        protected TypeReference UnwrapType(JSExpression expression)
        {
            var type = expression as JSType;

            var invocation = expression as JSInvocationExpression;
            if (invocation != null) {
                var firstArg = invocation.Arguments.FirstOrDefault();
                type = type ?? firstArg as JSType;
            }

            if (type != null)
                return type.Type;

            throw new NotImplementedException(String.Format(
                "Unrecognized type expression: {0}",
                expression
            ));
        }
Exemplo n.º 59
0
        public static JSExpression CastToEnumType (JSExpression value, TypeReference type, TypeSystem typeSystem) {
            if (IsNullableEnum(type)) {
                // Handle casts like <int> -> <Enum?> by doing a two stage cast:
                // <int> -> <Enum> -> <Enum?>
                // Issue #154

                var git = (GenericInstanceType)type;
                var casted = JSCastExpression.New(
                    value, git.GenericArguments[0], typeSystem, true
                );
                var coerced = JSChangeTypeExpression.New(
                    casted, type, typeSystem
                );
                return coerced;
            } else {
                return JSCastExpression.New(
                    value, type, typeSystem, true
                );
            }
        }
Exemplo n.º 60
0
        public static void CheckReturnValue(MethodInfo method, JSExpression returnValue, TypeSystem typeSystem)
        {
            if (method == null)
                return;

            var resultType = returnValue.GetActualType(typeSystem);
            var resultIsPackedArray = PackedArrayUtil.IsPackedArrayType(resultType);

            var returnValueAttribute = method.Metadata.GetAttribute("JSIL.Meta.JSPackedArrayReturnValueAttribute");
            if (returnValueAttribute != null) {
                if (!resultIsPackedArray)
                    throw new ArgumentException(
                        "Return value of method '" + method.Name + "' must be a packed array."
                    );
            } else {
                if (resultIsPackedArray)
                    throw new ArgumentException(
                        "Return value of method '" + method.Name + "' is a packed array. " +
                        "For this to be valid you must attach a JSPackedArrayReturnValueAttribute to the method."
                    );
            }
        }