public static void LinkIndyCallSite <T>(ref IndyCallSite <T> site, java.lang.invoke.CallSite cs, Exception x) where T : class // Delegate { #if !FIRST_PASS IndyCallSite <T> ics; if (x != null || cs == null || (ics = cs.ics as IndyCallSite <T>) == null) { x = MapException <Exception>(x ?? (cs == null ? (Exception) new java.lang.ClassCastException("bootstrap method failed to produce a CallSite") : new java.lang.invoke.WrongMethodTypeException()), MapFlags.None); java.lang.invoke.MethodType type = LoadMethodType <T>(); ics = new IndyCallSite <T>((T) java.lang.invoke.MethodHandles.dropArguments( java.lang.invoke.MethodHandles.foldArguments( java.lang.invoke.MethodHandles.throwException(type.returnType(), typeof(java.lang.BootstrapMethodError)), new ConstantMethodHandle((MH <Exception, java.lang.BootstrapMethodError>)CreateBootstrapException).bindTo(x)), 0, type.parameterArray()) .vmtarget, false); } IndyCallSite <T> curr = site; if (curr.IsBootstrap) { Interlocked.CompareExchange(ref site, ics, curr); } #endif }
public static java.lang.invoke.MethodType DynamicLoadMethodType(ref java.lang.invoke.MethodType cache, string sig, [email protected] callerID) { if (cache == null) { DynamicLoadMethodTypeImpl(ref cache, sig, callerID); } return(cache); }
internal bool TrySetType(java.lang.invoke.MethodType newType) { if (weakRef == null) { return(Interlocked.CompareExchange(ref weakRef, new WeakReference(newType), null) == null); } return(Type == newType); }
public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { #if !WINRT #if FIRST_PASS return(null); #else TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { #if NO_REF_EMIT java.lang.invoke.MethodType methodType = MethodHandleUtil.GetDelegateMethodType(delegateType); if (methodType.parameterCount() > MethodHandleUtil.MaxArity) { throw new NotImplementedException(); } java.lang.invoke.MethodHandle exception = java.lang.invoke.MethodHandles.publicLookup() .findConstructor(mw == null || mw.IsStatic ? typeof(java.lang.AbstractMethodError) : typeof(java.lang.IllegalAccessError), java.lang.invoke.MethodType.methodType(typeof(void), typeof(string))) .bindTo(tw.Name + ".Invoke" + sig); return(Delegate.CreateDelegate(delegateType, java.lang.invoke.MethodHandles.dropArguments( java.lang.invoke.MethodHandles.foldArguments(java.lang.invoke.MethodHandles.throwException(methodType.returnType(), exception.type().returnType()), exception), 0, methodType.parameterArray()).vmtarget, "Invoke")); #else MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); #endif } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } #endif #else throw new NotImplementedException(); #endif }
public static void DynamicLinkIndyCallSite <T>(ref IndyCallSite <T> site, java.lang.invoke.CallSite cs, Exception x, string signature, [email protected] callerID) where T : class // Delegate { #if !FIRST_PASS // when a CallSite is first constructed, it doesn't call MethodHandleNatives.setCallSiteTargetNormal(), // so we have to check if we need to initialize it here (i.e. attach an IndyCallSite<T> to it) if (cs != null) { if (cs.ics == null) { Java_java_lang_invoke_MethodHandleNatives.InitializeCallSite(cs); } lock (cs.ics) { cs.ics.SetTarget(cs.target); } } java.lang.invoke.MethodType typeCache = null; IndyCallSite <T> ics; if (x != null || cs == null || cs.type() != DynamicLoadMethodType(ref typeCache, signature, callerID)) { x = MapException <Exception>(x ?? (cs == null ? (Exception) new java.lang.ClassCastException("bootstrap method failed to produce a CallSite") : new java.lang.invoke.WrongMethodTypeException()), MapFlags.None); java.lang.invoke.MethodType type = LoadMethodType <T>(); java.lang.invoke.MethodHandle exc = x is java.lang.BootstrapMethodError ? java.lang.invoke.MethodHandles.constant(typeof(java.lang.BootstrapMethodError), x) : java.lang.invoke.MethodHandles.publicLookup().findConstructor(typeof(java.lang.BootstrapMethodError), java.lang.invoke.MethodType.methodType(typeof(void), typeof(string), typeof(Exception))) .bindTo("call site initialization exception").bindTo(x); ics = new IndyCallSite <T>(); ((IIndyCallSite)ics).SetTarget( java.lang.invoke.MethodHandles.dropArguments( java.lang.invoke.MethodHandles.foldArguments( java.lang.invoke.MethodHandles.throwException(type.returnType(), typeof(java.lang.BootstrapMethodError)), exc), 0, type.parameterArray())); } else { ics = new IndyCallSite <T>(); ((IIndyCallSite)ics).SetTarget(cs.dynamicInvoker().asType(LoadMethodType <T>())); } IndyCallSite <T> curr = site; if (curr.IsBootstrap) { Interlocked.CompareExchange(ref site, ics, curr); } #endif }
private static java.lang.invoke.MethodHandle DynamicLoadMethodHandleImpl(int kind, string clazz, string name, string sig, [email protected] callerID) { #if FIRST_PASS return(null); #else java.lang.Class refc = LoadTypeWrapper(clazz, callerID).ClassObject; try { switch ((ClassFile.RefKind)kind) { case ClassFile.RefKind.getStatic: case ClassFile.RefKind.putStatic: case ClassFile.RefKind.getField: case ClassFile.RefKind.putField: java.lang.Class type = ClassLoaderWrapper.FromCallerID(callerID).FieldTypeWrapperFromSig(sig).ClassObject; return(java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(callerID.getCallerClass(), kind, refc, name, type)); default: java.lang.invoke.MethodType mt = null; DynamicLoadMethodType(ref mt, sig, callerID); // HACK linkMethodHandleConstant is broken for MethodHandle.invoke[Exact] if (kind == (int)ClassFile.RefKind.invokeVirtual && refc == CoreClasses.java.lang.invoke.MethodHandle.Wrapper.ClassObject) { switch (name) { case "invokeExact": return(java.lang.invoke.MethodHandles.exactInvoker(mt)); case "invoke": return(java.lang.invoke.MethodHandles.invoker(mt)); } } java.lang.Class caller = callerID.getCallerClass(); DynamicTypeWrapper.FinishContext.HostCallerID hostCallerID = callerID as DynamicTypeWrapper.FinishContext.HostCallerID; if (hostCallerID != null) { caller = hostCallerID.host.ClassObject; } return(java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(caller, kind, refc, name, mt)); } } catch (RetargetableJavaException x) { throw x.ToJava(); } #endif }
private static void DynamicLoadMethodTypeImpl(ref java.lang.invoke.MethodType cache, string sig, [email protected] callerID) { #if !FIRST_PASS try { ClassLoaderWrapper loader = ClassLoaderWrapper.FromCallerID(callerID); TypeWrapper[] args = loader.ArgTypeWrapperListFromSig(sig, LoadMode.LoadOrThrow); java.lang.Class[] ptypes = new java.lang.Class[args.Length]; for (int i = 0; i < ptypes.Length; i++) { ptypes[i] = args[i].ClassObject; } Interlocked.CompareExchange(ref cache, java.lang.invoke.MethodType.methodType(loader.RetTypeWrapperFromSig(sig, LoadMode.LoadOrThrow).ClassObject, ptypes), null); } catch (RetargetableJavaException x) { throw x.ToJava(); } #endif }
public static T GetDelegateForInvoke<T>(global::java.lang.invoke.MethodHandle h, java.lang.invoke.MethodType realType, ref InvokeCache<T> cache) where T : class { #if FIRST_PASS return null; #else T del; if (cache.Type == h.type() && (del = (h.isVarargsCollector() ? cache.varArg : cache.fixedArg)) != null) { return del; } del = h.form.vmentry.vmtarget as T; if (del == null) { global::java.lang.invoke.MethodHandle adapter = global::java.lang.invoke.MethodHandles.exactInvoker(h.type()); if (h.isVarargsCollector()) { adapter = adapter.asVarargsCollector(h.type().parameterType(h.type().parameterCount() - 1)); } // if realType is set, the delegate contains erased unloadable types if (realType != null) { adapter = adapter.asType(realType.insertParameterTypes(0, [email protected]<java.lang.invoke.MethodHandle>.Value)).asFixedArity(); } adapter = adapter.asType(MethodHandleUtil.GetDelegateMethodType(typeof(T))); del = GetDelegateForInvokeExact<T>(adapter); if (cache.TrySetType(h.type())) { if (h.isVarargsCollector()) { cache.varArg = del; } else { cache.fixedArg = del; } } } return del; #endif }
public static java.lang.invoke.MethodHandle DynamicEraseInvokeExact(java.lang.invoke.MethodHandle mh, java.lang.invoke.MethodType expected, java.lang.invoke.MethodType target) { #if FIRST_PASS return(null); #else if (mh.type() != expected) { throw new java.lang.invoke.WrongMethodTypeException(); } return(java.lang.invoke.MethodHandles.explicitCastArguments(mh, target)); #endif }
internal bool TrySetType(java.lang.invoke.MethodType newType) { Interlocked.CompareExchange(ref type, newType, null); return(type == newType); }
private static java.lang.invoke.MethodHandle DynamicLoadMethodHandleImpl(int kind, string clazz, string name, string sig, [email protected] callerID) { #if FIRST_PASS return(null); #else java.lang.invoke.MethodHandles.Lookup lookup = new java.lang.invoke.MethodHandles.Lookup(callerID.getCallerClass(), java.lang.invoke.MethodHandles.Lookup.PUBLIC | java.lang.invoke.MethodHandles.Lookup.PRIVATE | java.lang.invoke.MethodHandles.Lookup.PROTECTED | java.lang.invoke.MethodHandles.Lookup.PACKAGE, true); java.lang.Class refc = LoadTypeWrapper(clazz, callerID).ClassObject; try { switch ((ClassFile.RefKind)kind) { case ClassFile.RefKind.getStatic: case ClassFile.RefKind.putStatic: case ClassFile.RefKind.getField: case ClassFile.RefKind.putField: java.lang.Class type = ClassLoaderWrapper.FromCallerID(callerID).FieldTypeWrapperFromSig(sig).ClassObject; switch ((ClassFile.RefKind)kind) { case ClassFile.RefKind.getStatic: return(lookup.findStaticGetter(refc, name, type)); case ClassFile.RefKind.putStatic: return(lookup.findStaticSetter(refc, name, type)); case ClassFile.RefKind.getField: return(lookup.findGetter(refc, name, type)); case ClassFile.RefKind.putField: return(lookup.findSetter(refc, name, type)); default: throw new InvalidOperationException(); } default: java.lang.invoke.MethodType mt = null; DynamicLoadMethodType(ref mt, sig, callerID); switch ((ClassFile.RefKind)kind) { case ClassFile.RefKind.invokeInterface: return(lookup.findVirtual(refc, name, mt)); case ClassFile.RefKind.invokeSpecial: return(lookup.findSpecial(refc, name, mt, callerID.getCallerClass())); case ClassFile.RefKind.invokeStatic: return(lookup.findStatic(refc, name, mt)); case ClassFile.RefKind.invokeVirtual: return(lookup.findVirtual(refc, name, mt)); case ClassFile.RefKind.newInvokeSpecial: return(lookup.findConstructor(refc, mt)); default: throw new InvalidOperationException(); } } } catch (RetargetableJavaException x) { throw x.ToJava(); } catch (java.lang.ReflectiveOperationException x) { throw new java.lang.IncompatibleClassChangeError().initCause(x); } #endif }