public void VisitNode(JSResultReferenceExpression rre) { var invocation = (rre.Referent as JSInvocationExpression); // When passing a packed array element directly to a function, use a proxy instead. // This allows hoisting to operate when the call is inside a loop, and it reduces GC pressure (since we basically make the struct unpack occur on-demand). if ( (ParentNode is JSInvocationExpression) && (invocation != null) && (invocation.JSMethod != null) && invocation.JSMethod.Reference.FullName.Contains("JSIL.Runtime.IPackedArray") && invocation.JSMethod.Reference.FullName.Contains("get_Item(") && Configuration.CodeGenerator.AggressivelyUseElementProxies.GetValueOrDefault(false) ) { var elementType = invocation.GetActualType(TypeSystem); var replacement = new JSNewPackedArrayElementProxy( invocation.ThisReference, invocation.Arguments.First(), elementType ); ParentNode.ReplaceChild(rre, replacement); VisitReplacement(replacement); return; } VisitChildren(rre); }
public void VisitNode (JSResultReferenceExpression rre) { var invocation = (rre.Referent as JSInvocationExpression); // When passing a packed array element directly to a function, use a proxy instead. // This allows hoisting to operate when the call is inside a loop, and it reduces GC pressure (since we basically make the struct unpack occur on-demand). if ( (ParentNode is JSInvocationExpression) && (invocation != null) && (invocation.JSMethod != null) && invocation.JSMethod.Reference.FullName.Contains("JSIL.Runtime.IPackedArray") && invocation.JSMethod.Reference.FullName.Contains("get_Item(") && Configuration.CodeGenerator.AggressivelyUseElementProxies.GetValueOrDefault(false) ) { var elementType = invocation.GetActualType(TypeSystem); var replacement = new JSNewPackedArrayElementProxy( invocation.ThisReference, invocation.Arguments.First(), elementType ); ParentNode.ReplaceChild(rre, replacement); VisitReplacement(replacement); return; } VisitChildren(rre); }
public void VisitNode(JSResultReferenceExpression rre) { VisitChildren(rre); if (ResultReferenceReplacement != null) { var newRre = ResultReferenceReplacement; ResultReferenceReplacement = null; ParentNode.ReplaceChild(rre, newRre); VisitReplacement(newRre); } }
public void VisitNode(JSResultReferenceExpression rre) { VisitChildren(rre); if (_ResultReferenceReplacement != null) { var replacement = _ResultReferenceReplacement; _ResultReferenceReplacement = null; ParentNode.ReplaceChild(rre, replacement); VisitReplacement(replacement); } }
public void VisitNode(JSResultReferenceExpression rre) { ReplacedInvocation = false; VisitChildren(rre); // If a getter invocation that returned a struct was replaced, there's // now a result reference expression that needs to be removed if (ReplacedInvocation && !(rre.Children.First() is JSInvocationExpressionBase)) { var replacement = rre.Children.First(); ParentNode.ReplaceChild(rre, replacement); } }
public void VisitNode (JSResultReferenceExpression rre) { VisitChildren(rre); if (_ResultReferenceReplacement != null) { var replacement = _ResultReferenceReplacement; _ResultReferenceReplacement = null; ParentNode.ReplaceChild(rre, replacement); VisitReplacement(replacement); } }
public void VisitNode(JSResultReferenceExpression rre) { ReplacedInvocation = false; VisitChildren(rre); // If a getter invocation that returned a struct was replaced, there's // now a result reference expression that needs to be removed if (ReplacedInvocation && !(rre.Children.First() is JSInvocationExpressionBase)) { var replacement = rre.Children.First(); ParentNode.ReplaceChild(rre, replacement); } }
private JSExpression ConstructInvocation ( JSPropertyAccess pa, JSExpression argument = null ) { JSExpression[] arguments; if (argument == null) arguments = new JSExpression[0]; else arguments = new JSExpression[] { argument }; var originalMethod = pa.OriginalMethod; var declaringType = originalMethod.Reference.DeclaringType; var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType); var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem); var isSelf = TypeUtil.TypesAreAssignable( TypeInfo, thisReferenceType, declaringType ); // ILSpy converts compound assignments from: // x.set_Value(x.get_Value + n) // to // x.get_Value += n; // so we have to detect this and reconstruct the correct method // references. var actualMethod = originalMethod; var correctName = String.Format( "{0}_{1}", pa.IsWrite ? "set" : "get", pa.Property.Property.ShortName ); if (!actualMethod.Reference.Name.Contains(correctName)) { var dt = originalMethod.Method.DeclaringType; var actualMethodInfo = dt.Members.Values .OfType<MethodInfo>().FirstOrDefault( (m) => ( m.Name.Contains(correctName) && m.DeclaringType == originalMethod.Method.DeclaringType ) ); MethodReference actualMethodReference = actualMethodInfo.Member; if (originalMethod.Reference is GenericInstanceMethod) { throw new InvalidDataException("Reconstructing an invocation of a generic instance method? Shouldn't be possible."); } else if (declaringType is GenericInstanceType) { var declaringGit = (GenericInstanceType)declaringType; var returnType = actualMethodReference.ReturnType; if (TypeUtil.IsOpenType(returnType)) { var actualReturnType = JSExpression.SubstituteTypeArgs(TypeInfo, actualMethodReference.ReturnType, actualMethodReference); returnType = actualReturnType; } actualMethodReference = new MethodReference( actualMethodReference.Name, returnType, declaringGit ); } actualMethod = new JSMethod( actualMethodReference, actualMethodInfo, originalMethod.MethodTypes, originalMethod.GenericArguments ); } bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis( declaringType, declaringTypeDef, originalMethod.Method.DeclaringType, isSelf, thisReferenceType, originalMethod.Method ); JSInvocationExpressionBase invocation; if (pa.Property.Property.IsStatic) invocation = JSInvocationExpression.InvokeStatic( actualMethod.Reference.DeclaringType, actualMethod, arguments ); else if (needsExplicitThis) invocation = JSInvocationExpression.InvokeBaseMethod( actualMethod.Reference.DeclaringType, actualMethod, pa.ThisReference, arguments ); else invocation = JSInvocationExpression.InvokeMethod( pa.OriginalType, actualMethod, pa.ThisReference, arguments ); JSExpression replacement; if (TypeUtil.IsStruct(pa.Property.Property.ReturnType)) replacement = new JSResultReferenceExpression(invocation); else replacement = invocation; return replacement; }
public void VisitNode (JSResultReferenceExpression rre) { VisitChildren(rre); if (ResultReferenceReplacement != null) { var newRre = ResultReferenceReplacement; ResultReferenceReplacement = null; ParentNode.ReplaceChild(rre, newRre); VisitReplacement(newRre); } }
private JSExpression ConstructInvocation( JSPropertyAccess pa, JSExpression argument = null ) { JSExpression[] arguments; if (argument == null) { arguments = new JSExpression[0]; } else { arguments = new JSExpression[] { argument } }; var originalMethod = pa.OriginalMethod; var declaringType = originalMethod.Reference.DeclaringType; var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType); var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem); var isSelf = TypeUtil.TypesAreAssignable( TypeInfo, thisReferenceType, declaringType ); // ILSpy converts compound assignments from: // x.set_Value(x.get_Value + n) // to // x.get_Value += n; // so we have to detect this and reconstruct the correct method // references. var actualMethod = originalMethod; var correctName = String.Format( "{0}_{1}", pa.IsWrite ? "set" : "get", pa.Property.Property.ShortName ); if (!actualMethod.Reference.Name.Contains(correctName)) { var dt = originalMethod.Method.DeclaringType; var actualMethodInfo = dt.Members.Values .OfType <MethodInfo>().FirstOrDefault( (m) => ( m.Name.Contains(correctName) && m.DeclaringType == originalMethod.Method.DeclaringType ) ); MethodReference actualMethodReference = actualMethodInfo.Member; if (originalMethod.Reference is GenericInstanceMethod) { throw new InvalidDataException("Reconstructing an invocation of a generic instance method? Shouldn't be possible."); } else if (declaringType is GenericInstanceType) { var declaringGit = (GenericInstanceType)declaringType; var returnType = actualMethodReference.ReturnType; if (TypeUtil.IsOpenType(returnType)) { var actualReturnType = JSExpression.SubstituteTypeArgs(TypeInfo, actualMethodReference.ReturnType, actualMethodReference); returnType = actualReturnType; } actualMethodReference = new MethodReference( actualMethodReference.Name, returnType, declaringGit ); } actualMethod = new JSMethod( actualMethodReference, actualMethodInfo, originalMethod.MethodTypes, originalMethod.GenericArguments ); } bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis( declaringType, declaringTypeDef, originalMethod.Method.DeclaringType, isSelf, thisReferenceType, originalMethod.Method ); JSInvocationExpressionBase invocation; if (pa.Property.Property.IsStatic) { invocation = JSInvocationExpression.InvokeStatic( actualMethod.Reference.DeclaringType, actualMethod, arguments ); } else if (needsExplicitThis) { invocation = JSInvocationExpression.InvokeBaseMethod( actualMethod.Reference.DeclaringType, actualMethod, pa.ThisReference, arguments ); } else { invocation = JSInvocationExpression.InvokeMethod( pa.OriginalType, actualMethod, pa.ThisReference, arguments ); } JSExpression replacement; if (TypeUtil.IsStruct(pa.Property.Property.ReturnType)) { replacement = new JSResultReferenceExpression(invocation); } else { replacement = invocation; } return(replacement); }
private JSExpression ConstructInvocation( JSPropertyAccess pa, JSExpression argument = null ) { JSExpression[] arguments; if (argument == null) arguments = new JSExpression[0]; else arguments = new JSExpression[] { argument }; var originalMethod = pa.OriginalMethod; var declaringType = originalMethod.Reference.DeclaringType; var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType); var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem); var isSelf = TypeUtil.TypesAreAssignable( TypeInfo, thisReferenceType, declaringType ); bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis( declaringType, declaringTypeDef, originalMethod.Method.DeclaringType, isSelf, thisReferenceType, originalMethod.Method ); JSInvocationExpressionBase invocation; if (pa.Property.Property.IsStatic) invocation = JSInvocationExpression.InvokeStatic( pa.OriginalMethod.Reference.DeclaringType, pa.OriginalMethod, arguments ); else if (needsExplicitThis) invocation = JSInvocationExpression.InvokeBaseMethod( pa.OriginalMethod.Reference.DeclaringType, pa.OriginalMethod, pa.ThisReference, arguments ); else invocation = JSInvocationExpression.InvokeMethod( pa.OriginalMethod, pa.ThisReference, arguments ); JSExpression replacement; if (TypeUtil.IsStruct(pa.Property.Property.ReturnType)) replacement = new JSResultReferenceExpression(invocation); else replacement = invocation; return replacement; }