public void VisitNode(JSInvocationExpression invocation) { var jsm = invocation.JSMethod; MethodInfo method = null; if (jsm != null) { method = jsm.Method; } bool isOverloaded = (method != null) && method.IsOverloadedRecursive && !method.Metadata.HasAttribute("JSIL.Meta.JSRuntimeDispatch"); if (isOverloaded && JavascriptAstEmitter.CanUseFastOverloadDispatch(method)) { isOverloaded = false; } if ((method != null) && method.DeclaringType.IsInterface) { // HACK if (!PackedArrayUtil.IsPackedArrayType(jsm.Reference.DeclaringType)) { CacheInterfaceMember(jsm.Reference.DeclaringType, jsm.Identifier); } } if ((jsm != null) && (method != null) && isOverloaded) { CacheSignature(jsm.Reference, method.Signature, false); } VisitChildren(invocation); }
/// <summary> /// Writes an interface member reference to the output. /// </summary> public void WriteInterfaceMemberToOutput( JavascriptFormatter output, JavascriptAstEmitter emitter, JSFunctionExpression enclosingFunction, JSMethod jsMethod, JSExpression method, TypeReferenceContext referenceContext ) { int index; var record = new CachedInterfaceMemberRecord(jsMethod.Reference.DeclaringType, jsMethod.Identifier); 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(); emitter.Visit(method); } else { output.WriteRaw("$IM{0:X2}()", index); } }
protected void TranslateModule(DecompilerContext context, JavascriptFormatter output, ModuleDefinition module, List<Action> initializer, HashSet<TypeDefinition> sealedTypes, bool stubbed) { var moduleInfo = TypeInfoProvider.GetModuleInformation(module); if (moduleInfo.IsIgnored) return; context.CurrentModule = module; var js = new JSSpecialIdentifiers(context.CurrentModule.TypeSystem); var jsil = new JSILIdentifier(context.CurrentModule.TypeSystem, js); // Probably should be an argument, not a member variable... AstEmitter = new JavascriptAstEmitter( output, jsil, context.CurrentModule.TypeSystem, this.TypeInfoProvider ); foreach (var typedef in module.Types) ForwardDeclareType(context, output, typedef); foreach (var typedef in module.Types) { TranslateTypeDefinition(context, output, typedef, initializer, stubbed); SealType(context, output, typedef, sealedTypes); } }