Imported Upstream version 3.8.0

Former-commit-id: 6a76a29bd07d86e57c6c8da45c65ed5447d38a61
This commit is contained in:
Jo Shields
2014-09-04 09:07:35 +01:00
parent a575963da9
commit fe777c5c82
1062 changed files with 12460 additions and 5983 deletions

View File

@@ -5,12 +5,11 @@
// Miguel de Icaza (miguel@ximian.com)
// Daniel Stodden (stodden@in.tum.de)
// Dietmar Maurer (dietmar@ximian.com)
// Marek Safar (marek.safar@gmail.com)
//
// (C) Ximian, Inc. http://www.ximian.com
//
//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
// Copyright 2014 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@@ -41,9 +40,11 @@ using System.Runtime.InteropServices;
namespace System
{
/* Contains the rarely used fields of Delegate */
class DelegateData {
sealed class DelegateData
{
public Type target_type;
public string method_name;
public bool curried_first_arg;
}
[ClassInterface (ClassInterfaceType.AutoDual)]
@@ -230,6 +231,8 @@ namespace System
return null;
bool argsMatch;
DelegateData delegate_data = new DelegateData ();
if (target != null) {
if (!method.IsStatic) {
argsMatch = arg_type_match_this (target.GetType (), method.DeclaringType, true);
@@ -238,7 +241,9 @@ namespace System
} else {
argsMatch = arg_type_match (target.GetType (), args [0].ParameterType);
for (int i = 1; i < args.Length; i++)
argsMatch &= arg_type_match (delargs [i - 1].ParameterType, args [i].ParameterType);
argsMatch &= arg_type_match (delargs [i - 1].ParameterType, args [i].ParameterType);
delegate_data.curried_first_arg = true;
}
} else {
if (!method.IsStatic) {
@@ -259,6 +264,8 @@ namespace System
argsMatch = !(args [0].ParameterType.IsValueType || args [0].ParameterType.IsByRef) && allowClosed;
for (int i = 0; i < delargs.Length; i++)
argsMatch &= arg_type_match (delargs [i].ParameterType, args [i + 1].ParameterType);
delegate_data.curried_first_arg = true;
} else {
argsMatch = true;
for (int i = 0; i < args.Length; i++)
@@ -276,6 +283,8 @@ namespace System
Delegate d = CreateDelegate_internal (type, target, method, throwOnBindFailure);
if (d != null)
d.original_method_info = method;
if (delegate_data != null)
d.data = delegate_data;
return d;
}
@@ -398,6 +407,21 @@ namespace System
return DynamicInvokeImpl (args);
}
void InitializeDelegateData ()
{
DelegateData delegate_data = new DelegateData ();
if (method_info.IsStatic) {
if (m_target != null) {
delegate_data.curried_first_arg = true;
} else {
MethodInfo invoke = GetType ().GetMethod ("Invoke");
if (invoke.GetParametersCount () + 1 == method_info.GetParametersCount ())
delegate_data.curried_first_arg = true;
}
}
this.data = delegate_data;
}
protected virtual object DynamicInvokeImpl (object[] args)
{
if (Method == null) {
@@ -408,20 +432,34 @@ namespace System
method_info = m_target.GetType ().GetMethod (data.method_name, mtypes);
}
if (Method.IsStatic && (args != null ? args.Length : 0) == Method.GetParametersCount () - 1) {
var target = m_target;
if (this.data == null)
InitializeDelegateData ();
if (Method.IsStatic) {
//
// The delegate is bound to m_target
if (args != null) {
object[] newArgs = new object [args.Length + 1];
args.CopyTo (newArgs, 1);
newArgs [0] = m_target;
args = newArgs;
} else {
args = new object [] { m_target };
//
if (data.curried_first_arg) {
if (args == null) {
args = new [] { target };
} else {
Array.Resize (ref args, args.Length + 1);
Array.Copy (args, 0, args, 1, args.Length - 1);
args [0] = target;
}
target = null;
}
} else {
if (m_target == null && args != null && args.Length > 0) {
target = args [0];
Array.Copy (args, 1, args, 0, args.Length - 1);
Array.Resize (ref args, args.Length - 1);
}
return Method.Invoke (null, args);
}
return Method.Invoke (m_target, args);
return Method.Invoke (target, args);
}
public virtual object Clone ()
@@ -440,8 +478,13 @@ namespace System
/* Uncommon case */
if (d.data != null && data != null)
return (d.data.target_type == data.target_type && d.data.method_name == data.method_name);
else
else {
if (d.data != null)
return d.data.target_type == null;
if (data != null)
return data.target_type == null;
return false;
}
}
return true;
}