Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.cs')
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.cs300
1 files changed, 0 insertions, 300 deletions
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.cs
deleted file mode 100644
index 3875af308b9..00000000000
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.cs
+++ /dev/null
@@ -1,300 +0,0 @@
-/* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Apache License, Version 2.0, please send an email to
- * ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-#if FEATURE_REFEMIT
-using System.Reflection.Emit;
-#endif
-using System.Security;
-using Microsoft.Scripting.Runtime;
-using Microsoft.Scripting.Utils;
-
-namespace Microsoft.Scripting.Interpreter {
- public abstract partial class CallInstruction : Instruction {
- public abstract MethodInfo Info { get; }
-
- /// <summary>
- /// The number of arguments including "this" for instance methods.
- /// </summary>
- public abstract int ArgumentCount { get; }
-
- #region Construction
-
- internal CallInstruction() { }
-
- private static readonly Dictionary<MethodInfo, CallInstruction> _cache = new Dictionary<MethodInfo, CallInstruction>();
-
- /// <exception cref="SecurityException">Instruction can't be created due to insufficient privileges.</exception>
- public static CallInstruction Create(MethodInfo info) {
- return Create(info, info.GetParameters());
- }
-
- /// <exception cref="SecurityException">Instruction can't be created due to insufficient privileges.</exception>
- public static CallInstruction Create(MethodInfo info, ParameterInfo[] parameters) {
- int argumentCount = parameters.Length;
- if (!info.IsStatic) {
- argumentCount++;
- }
-
- // A workaround for CLR bug #796414 (Unable to create delegates for Array.Get/Set):
- // T[]::Address - not supported by ETs due to T& return value
- if (info.DeclaringType != null && info.DeclaringType.IsArray && (info.Name == "Get" || info.Name == "Set")) {
- return GetArrayAccessor(info, argumentCount);
- }
-
-#if FULL_AOT_RUNTIME
- return new MethodInfoCallInstruction(info, argumentCount);
-#else
- if (ReflectionUtils.IsDynamicMethod(info) || !info.IsStatic && info.DeclaringType.IsValueType()) {
- return new MethodInfoCallInstruction(info, argumentCount);
- }
-
- if (argumentCount >= MaxHelpers) {
- // no delegate for this size, fallback to reflection invoke
- return new MethodInfoCallInstruction(info, argumentCount);
- }
-
- foreach (ParameterInfo pi in parameters) {
- if (pi.ParameterType.IsByRef) {
- // we don't support ref args via generics.
- return new MethodInfoCallInstruction(info, argumentCount);
- }
- }
-
- // see if we've created one w/ a delegate
- CallInstruction res;
- if (ShouldCache(info)) {
- lock (_cache) {
- if (_cache.TryGetValue(info, out res)) {
- return res;
- }
- }
- }
-
- // create it
- try {
- if (argumentCount < MaxArgs) {
- res = FastCreate(info, parameters);
- } else {
- res = SlowCreate(info, parameters);
- }
- } catch (TargetInvocationException tie) {
- if (!(tie.InnerException is NotSupportedException)) {
- throw tie.InnerException;
- }
-
- res = new MethodInfoCallInstruction(info, argumentCount);
- } catch (NotSupportedException) {
- // if Delegate.CreateDelegate can't handle the method fallback to
- // the slow reflection version. For example this can happen w/
- // a generic method defined on an interface and implemented on a class or
- // a virtual generic method.
- res = new MethodInfoCallInstruction(info, argumentCount);
- }
-
- // cache it for future users if it's a reasonable method to cache
- if (ShouldCache(info)) {
- lock (_cache) {
- _cache[info] = res;
- }
- }
-
- return res;
-#endif
- }
-
- private static CallInstruction GetArrayAccessor(MethodInfo info, int argumentCount) {
- Type arrayType = info.DeclaringType;
- bool isGetter = info.Name == "Get";
- switch (arrayType.GetArrayRank()) {
- case 1:
- return Create(isGetter ?
- arrayType.GetMethod("GetValue", new[] { typeof(int)}) :
- new Action<Array, int, object>(ArrayItemSetter1).GetMethodInfo()
- );
-
- case 2:
- return Create(isGetter ?
- arrayType.GetMethod("GetValue", new[] { typeof(int), typeof(int) }) :
- new Action<Array, int, int, object>(ArrayItemSetter2).GetMethodInfo()
- );
-
- case 3:
- return Create(isGetter ?
- arrayType.GetMethod("GetValue", new[] { typeof(int), typeof(int), typeof(int) }) :
- new Action<Array, int, int, int, object>(ArrayItemSetter3).GetMethodInfo()
- );
-
- default:
- return new MethodInfoCallInstruction(info, argumentCount);
- }
- }
-
- public static void ArrayItemSetter1(Array array, int index0, object value) {
- array.SetValue(value, index0);
- }
-
- public static void ArrayItemSetter2(Array array, int index0, int index1, object value) {
- array.SetValue(value, index0, index1);
- }
-
- public static void ArrayItemSetter3(Array array, int index0, int index1, int index2, object value) {
- array.SetValue(value, index0, index1, index2);
- }
-
- private static bool ShouldCache(MethodInfo info) {
- return !ReflectionUtils.IsDynamicMethod(info);
- }
-
- /// <summary>
- /// Gets the next type or null if no more types are available.
- /// </summary>
- private static Type TryGetParameterOrReturnType(MethodInfo target, ParameterInfo[] pi, int index) {
- if (!target.IsStatic) {
- index--;
- if (index < 0) {
- return target.DeclaringType;
- }
- }
-
- if (index < pi.Length) {
- // next in signature
- return pi[index].ParameterType;
- }
-
- if (target.ReturnType == typeof(void) || index > pi.Length) {
- // no more parameters
- return null;
- }
-
- // last parameter on Invoke is return type
- return target.ReturnType;
- }
-
- private static bool IndexIsNotReturnType(int index, MethodInfo target, ParameterInfo[] pi) {
- return pi.Length != index || (pi.Length == index && !target.IsStatic);
- }
-
- /// <summary>
- /// Uses reflection to create new instance of the appropriate ReflectedCaller
- /// </summary>
- private static CallInstruction SlowCreate(MethodInfo info, ParameterInfo[] pis) {
- List<Type> types = new List<Type>();
- if (!info.IsStatic) types.Add(info.DeclaringType);
- foreach (ParameterInfo pi in pis) {
- types.Add(pi.ParameterType);
- }
- if (info.ReturnType != typeof(void)) {
- types.Add(info.ReturnType);
- }
- Type[] arrTypes = types.ToArray();
-
- return (CallInstruction)Activator.CreateInstance(GetHelperType(info, arrTypes), info);
- }
-
- #endregion
-
- #region Instruction
-
- public sealed override int ProducedStack { get { return Info.ReturnType == typeof(void) ? 0 : 1; } }
- public sealed override int ConsumedStack { get { return ArgumentCount; } }
-
- public sealed override string InstructionName {
- get { return "Call"; }
- }
-
- public override string ToString() {
- return "Call(" + Info + ")";
- }
-
- #endregion
- }
-
- internal sealed partial class MethodInfoCallInstruction : CallInstruction {
- private readonly MethodInfo _target;
- private readonly int _argumentCount;
-
- public override MethodInfo Info { get { return _target; } }
- public override int ArgumentCount { get { return _argumentCount; } }
-
- internal MethodInfoCallInstruction(MethodInfo target, int argumentCount) {
- _target = target;
- _argumentCount = argumentCount;
- }
-
- public override object Invoke(params object[] args) {
- return InvokeWorker(args);
- }
-
- public override object InvokeInstance(object instance, params object[] args) {
- if (_target.IsStatic) {
- try {
- return _target.Invoke(null, args);
- } catch (TargetInvocationException e) {
- throw ExceptionHelpers.UpdateForRethrow(e.InnerException);
- }
- }
-
- try {
- return _target.Invoke(instance, args);
- } catch (TargetInvocationException e) {
- throw ExceptionHelpers.UpdateForRethrow(e.InnerException);
- }
- }
-
- private object InvokeWorker(params object[] args) {
- if (_target.IsStatic) {
- try {
- return _target.Invoke(null, args);
- } catch (TargetInvocationException e) {
- throw ExceptionHelpers.UpdateForRethrow(e.InnerException);
- }
- }
-
- try {
- return _target.Invoke(args[0], GetNonStaticArgs(args));
- } catch (TargetInvocationException e) {
- throw ExceptionHelpers.UpdateForRethrow(e.InnerException);
- }
- }
-
- private static object[] GetNonStaticArgs(object[] args) {
- object[] newArgs = new object[args.Length - 1];
- for (int i = 0; i < newArgs.Length; i++) {
- newArgs[i] = args[i + 1];
- }
- return newArgs;
- }
-
- public sealed override int Run(InterpretedFrame frame) {
- int first = frame.StackIndex - _argumentCount;
- object[] args = new object[_argumentCount];
- for (int i = 0; i < args.Length; i++) {
- args[i] = frame.Data[first + i];
- }
-
- object ret = Invoke(args);
- if (_target.ReturnType != typeof(void)) {
- frame.Data[first] = ret;
- frame.StackIndex = first + 1;
- } else {
- frame.StackIndex = first;
- }
- return 1;
- }
- }
-
-}