From 13411dd6be9a08e566d861958527d93ac565951d Mon Sep 17 00:00:00 2001 From: Igor Kiselev Date: Thu, 16 Jun 2016 18:56:38 -0700 Subject: [PATCH] Use methodKey accessor to eliminate closures in signature calls. --- JSIL.Libraries/Sources/JSIL.Core.js | 6 ++- JSIL/JavascriptAstEmitter.cs | 74 +++++++++++++++++++---------- JSIL/JavascriptFormatter.cs | 60 +++++++++++++++-------- 3 files changed, 95 insertions(+), 45 deletions(-) diff --git a/JSIL.Libraries/Sources/JSIL.Core.js b/JSIL.Libraries/Sources/JSIL.Core.js index 01151da3b..9527d7453 100644 --- a/JSIL.Libraries/Sources/JSIL.Core.js +++ b/JSIL.Libraries/Sources/JSIL.Core.js @@ -8081,6 +8081,10 @@ JSIL.InterfaceMethod = function (typeObject, methodName, methodInfo) { return this.signature != null ? JSIL.$GetSignaturePrefixForType(typeObject) + this.methodNonQualifiedKey : this.qualifiedName; }); + JSIL.SetLazyValueProperty(this, "methodKeyNonVirtual", function () { + return "i$" + this.methodKey; + }); + JSIL.SetLazyValueProperty(this, "methodNonQualifiedKey", function () { return this.signature != null ? this.signature.GetNamedKey(this.methodName, true) : this.methodName; }); @@ -8263,7 +8267,7 @@ JSIL.InterfaceMethod.prototype.$MakeCallMethod = function (isVirtual, isStatic) ? "CallVariantInterface" : "CallInterface"); - var methodKey = isStatic? this.methodNonQualifiedKey : (isVirtual ? this.methodKey : "i$" + this.methodKey); + var methodKey = isStatic ? this.methodNonQualifiedKey : (isVirtual ? this.methodKey : this.methodKeyNonVirtual); return this.$MakeInlineCacheBody(callType, methodKey, this.fallbackMethod); } else { diff --git a/JSIL/JavascriptAstEmitter.cs b/JSIL/JavascriptAstEmitter.cs index cec9ae79e..d52381a81 100644 --- a/JSIL/JavascriptAstEmitter.cs +++ b/JSIL/JavascriptAstEmitter.cs @@ -854,6 +854,9 @@ public void VisitNode (JSConditionalStructCopyExpression sce) { Output.WriteRaw("JSIL.CloneParameter"); Output.LPar(); Output.Identifier(sce.Parameter, ReferenceContext, false); + // IK TODO: pass to identifier if we need public interfece versus object + Output.Dot(); + Output.WriteRaw("__Type__"); Output.Comma(); Visit(sce.Struct); Output.RPar(); @@ -1134,7 +1137,7 @@ public void VisitNode (JSDefaultValueLiteral defaultValue) { Output.WriteRaw("null"); } else if (defaultValue.Value.IsGenericParameter) { VisitNode(new JSTernaryOperatorExpression( - new JSMemberReferenceExpression(new JSDotExpression(new JSType(defaultValue.Value), + new JSMemberReferenceExpression(new JSDotExpression(new JSTypeOfExpression(defaultValue.Value), new JSStringIdentifier("IsValueType"))), JSIL.CreateInstanceOfType(defaultValue.Value), JSLiteral.Null(defaultValue.Value), @@ -1217,14 +1220,10 @@ public void VisitNode (JSCachedTypeOfExpression cachedTypeOf) { public void VisitNode (JSTypeOfExpression toe) { Output.Identifier( toe.Type, ReferenceContext, IncludeTypeParens.Peek() - ); + ); - if (toe.Type is GenericParameter) { - // Generic parameters are type objects, not public interfaces - } else { - Output.Dot(); - Output.Identifier("__Type__"); - } + Output.Dot(); + Output.Identifier("__Type__"); } public void VisitNode(JSMethodOfExpression moe) @@ -2338,26 +2337,53 @@ public void VisitNode (JSInvocationExpression invocation) { }; if (isOverloaded) { - ReferenceContext.InvokingMethod = jsm.Reference; - SignatureCacher.WriteQualifiedSignatureToOutput( - Output, this, Stack.OfType().FirstOrDefault(), - jsm, - ReferenceContext - ); + if (!method.DeclaringType.IsInterface) { + if (isStatic) { + Visit(invocation.Type); + } else { + Visit(invocation.ThisReference, "ThisReference"); + } - Output.Dot(); - Output.WriteRaw(isStatic ? "CallStatic" : invocation.ExplicitThis ? "CallNonVirtual" : "Call"); + Output.OpenBracket(); + ReferenceContext.InvokingMethod = jsm.Reference; + SignatureCacher.WriteQualifiedSignatureToOutput( + Output, this, Stack.OfType().FirstOrDefault(), + jsm, + ReferenceContext + ); + Output.Dot(); + Output.WriteRaw(isStatic ? "methodNonQualifiedKey" : (invocation.ExplicitThis ? "methodKeyNonVirtual" : "methodKey")); + Output.CloseBracket(); - Output.LPar(); - if (!isStatic) { - Visit(invocation.ThisReference, "ThisReference"); - Output.Comma(); - } + Output.LPar(); + if (hasGenericArguments) { + Output.CommaSeparatedList(invocation.GenericArguments, ReferenceContext, ListValueType.TypeIdentifier); - genericArgs(); + if (hasArguments) + Output.Comma(); + } + } else { + ReferenceContext.InvokingMethod = jsm.Reference; + SignatureCacher.WriteQualifiedSignatureToOutput( + Output, this, Stack.OfType().FirstOrDefault(), + jsm, + ReferenceContext + ); - if (hasArguments) - Output.Comma(); + Output.Dot(); + Output.WriteRaw(isStatic ? "CallStatic" : invocation.ExplicitThis ? "CallNonVirtual" : "Call"); + + Output.LPar(); + if (!isStatic) { + Visit(invocation.ThisReference, "ThisReference"); + Output.Comma(); + } + + genericArgs(); + + if (hasArguments) + Output.Comma(); + } } else { if (isStatic) { if (!invocation.Type.IsNull) { diff --git a/JSIL/JavascriptFormatter.cs b/JSIL/JavascriptFormatter.cs index 85234ae30..362e8f76b 100644 --- a/JSIL/JavascriptFormatter.cs +++ b/JSIL/JavascriptFormatter.cs @@ -342,9 +342,9 @@ public void CommaSeparatedList (IEnumerable values, TypeReferenceContext else if (valueType == ListValueType.Identifier) Identifier(value as dynamic, context); else if (valueType == ListValueType.TypeIdentifier) - TypeIdentifier(value as dynamic, context, false); + TypeIdentifier(value as dynamic, context, false, false); else if (valueType == ListValueType.TypeReference) - TypeReference((TypeReference)value, context); + TypeReference((TypeReference) value, context); else WriteRaw(value.ToString()); }, @@ -528,14 +528,14 @@ protected void TypeReferenceInternal (GenericParameter gp, TypeReferenceContext } return; } else { - TypeIdentifier(resolved, context, false); + TypeIdentifier(resolved, context, false, true); return; } } } if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingMethodType)) { - TypeIdentifier(gp, context, false); + TypeIdentifier(gp, context, false, true); return; } @@ -871,11 +871,11 @@ public void Identifier (TypeReference type, TypeReferenceContext context, bool i if (type.FullName == "JSIL.Proxy.AnyType") WriteRaw("JSIL.AnyType"); else - TypeIdentifier(type as dynamic, context, includeParens); + TypeIdentifier(type as dynamic, context, includeParens, true); } - protected void TypeIdentifier (TypeInfo type, TypeReferenceContext context, bool includeParens) { - TypeIdentifier(type.Definition as dynamic, context, includeParens); + protected void TypeIdentifier (TypeInfo type, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { + TypeIdentifier(type.Definition as dynamic, context, includeParens, usePublicInterface); } protected bool EmitThisForParameter (GenericParameter gp) { @@ -891,7 +891,7 @@ protected bool EmitThisForParameter (GenericParameter gp) { return false; } - protected void TypeIdentifier (TypeReference type, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (TypeReference type, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { if (SignatureCacher.IsTypeArgument(type)) { WriteRaw(type.Name); return; @@ -939,7 +939,14 @@ protected void TypeIdentifier (TypeReference type, TypeReferenceContext context, Identifier(type.FullName); } - } else { + + if (usePublicInterface) + { + Dot(); + WriteRaw("__PublicInterface__"); + } + } + else { var info = TypeInfo.Get(type); if ((info != null) && (info.Replacement != null)) { WriteRaw(info.Replacement); @@ -967,16 +974,21 @@ protected void TypeIdentifier (TypeReference type, TypeReferenceContext context, type.FullName, EscapingMode.TypeIdentifier )); } + + if (!usePublicInterface) { + Dot(); + WriteRaw("__Type__"); + } } } - protected void TypeIdentifier (ByReferenceType type, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (ByReferenceType type, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { if (includeParens) LPar(); WriteRaw("JSIL.Reference.Of"); LPar(); - TypeIdentifier(type.ElementType as dynamic, context, false); + TypeIdentifier(type.ElementType as dynamic, context, false, true); RPar(); if (includeParens) { @@ -985,13 +997,13 @@ protected void TypeIdentifier (ByReferenceType type, TypeReferenceContext contex } } - protected void TypeIdentifier (ArrayType type, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (ArrayType type, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { if (includeParens) LPar(); WriteRaw("System.Array.Of"); LPar(); - TypeIdentifier(type.ElementType as dynamic, context, false); + TypeIdentifier(type.ElementType as dynamic, context, false, true); if (!type.IsVector) { Comma(); @@ -1001,6 +1013,10 @@ protected void TypeIdentifier (ArrayType type, TypeReferenceContext context, boo RPar(); } RPar(); + if (!usePublicInterface) { + Dot(); + WriteRaw("__Type__"); + } if (includeParens) { RPar(); @@ -1008,22 +1024,22 @@ protected void TypeIdentifier (ArrayType type, TypeReferenceContext context, boo } } - protected void TypeIdentifier (OptionalModifierType modopt, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (OptionalModifierType modopt, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { Identifier(modopt.ElementType as dynamic, context, includeParens); } - protected void TypeIdentifier (RequiredModifierType modreq, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (RequiredModifierType modreq, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { Identifier(modreq.ElementType as dynamic, context, includeParens); } - protected void TypeIdentifier (PointerType ptr, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (PointerType ptr, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { WriteRaw("JSIL.Pointer.Of"); LPar(); Identifier(ptr.ElementType as dynamic, context, includeParens); RPar(); } - protected void TypeIdentifier (GenericInstanceType type, TypeReferenceContext context, bool includeParens) { + protected void TypeIdentifier (GenericInstanceType type, TypeReferenceContext context, bool includeParens, bool usePublicInterface) { if (includeParens) LPar(); @@ -1034,6 +1050,10 @@ protected void TypeIdentifier (GenericInstanceType type, TypeReferenceContext co LPar(); CommaSeparatedList(type.GenericArguments, context, ListValueType.TypeIdentifier); RPar(); + if (!usePublicInterface) { + Dot(); + WriteRaw("__Type__"); + } if (includeParens) { RPar(); @@ -1330,7 +1350,7 @@ public void Signature (MethodReference method, MethodSignature signature, TypeRe : signature.ReturnType; if ((alwaysUseIdentifiers || context.EnclosingMethod != null) && !TypeUtil.IsOpenType(returnType, gp => !SignatureCacher.IsTypeArgument(gp))) - TypeIdentifier(returnType as dynamic, context, false); + TypeIdentifier(returnType as dynamic, context, false, true); else TypeReference(returnType, context); @@ -1340,7 +1360,7 @@ public void Signature (MethodReference method, MethodSignature signature, TypeRe WriteRaw("null"); else { if ((alwaysUseIdentifiers || context.EnclosingMethod != null) && !TypeUtil.IsOpenType(signature.ReturnType, gp => !SignatureCacher.IsTypeArgument(gp))) - TypeIdentifier(signature.ReturnType as dynamic, context, false); + TypeIdentifier(signature.ReturnType as dynamic, context, false, true); else TypeReference(signature.ReturnType, context); } @@ -1353,7 +1373,7 @@ public void Signature (MethodReference method, MethodSignature signature, TypeRe CommaSeparatedListCore( signature.ParameterTypes, (pt) => { if ((alwaysUseIdentifiers || context.EnclosingMethod != null) && !TypeUtil.IsOpenType(pt, gp => !SignatureCacher.IsTypeArgument(gp))) - TypeIdentifier(pt as dynamic, context, false); + TypeIdentifier(pt as dynamic, context, false, true); else TypeReference(pt, context); }