153 lines
6.5 KiB
C#
153 lines
6.5 KiB
C#
/*
|
||
Copyright (c) Microsoft Corporation
|
||
|
||
All rights reserved.
|
||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
||
compliance with the License. You may obtain a copy of the License
|
||
at http://www.apache.org/licenses/LICENSE-2.0
|
||
|
||
|
||
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
|
||
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||
|
||
|
||
See the Apache Version 2.0 License for specific language governing permissions and
|
||
limitations under the License.
|
||
|
||
*/
|
||
|
||
//
|
||
// <20> Microsoft Corporation. All rights reserved.
|
||
//
|
||
using System;
|
||
using System.IO;
|
||
using System.Reflection;
|
||
using System.Reflection.Emit;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
using System.Diagnostics;
|
||
using Microsoft.Research.DryadLinq;
|
||
|
||
namespace Microsoft.Research.DryadLinq.Internal
|
||
{
|
||
//these are involved in generated code for member lookup
|
||
//eg for direct access to fields of IndexedValue. and probably other situations too.
|
||
public delegate S GetObjFieldDelegate<T, S>(T obj);
|
||
public delegate void SetObjFieldDelegate<T, S>(T obj, S value);
|
||
|
||
public delegate S GetStructFieldDelegate<T, S>(out T obj);
|
||
public delegate void SetStructFieldDelegate<T, S>(out T obj, S value);
|
||
|
||
//this class is internal-public for Get ObjFieldDelegate etc.
|
||
public static class CodeGenHelper
|
||
{
|
||
public static GetObjFieldDelegate<T, S> GetObjField<T, S>(string fname)
|
||
{
|
||
Type typeT = typeof(T);
|
||
if (typeT.IsValueType)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
SR.Internal_CannotBeUsedForValueType);
|
||
}
|
||
FieldInfo finfo = typeT.GetField(fname, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
|
||
if (finfo == null)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
String.Format(SR.TypeDoesNotContainRequestedField, typeT.Name, fname));
|
||
}
|
||
DynamicMethod dm = new DynamicMethod("GetObjField",
|
||
typeof(S),
|
||
new Type[] { typeT },
|
||
typeT);
|
||
ILGenerator ilgen = dm.GetILGenerator();
|
||
ilgen.Emit(OpCodes.Ldarg_0);
|
||
ilgen.Emit(OpCodes.Ldfld, finfo);
|
||
ilgen.Emit(OpCodes.Ret);
|
||
|
||
return (GetObjFieldDelegate<T, S>)dm.CreateDelegate(typeof(GetObjFieldDelegate<T, S>));
|
||
}
|
||
|
||
public static SetObjFieldDelegate<T, S> SetObjField<T, S>(string fname)
|
||
{
|
||
Type typeT = typeof(T);
|
||
if (typeT.IsValueType)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
SR.Internal_CannotBeUsedForValueType);
|
||
}
|
||
FieldInfo finfo = typeT.GetField(fname, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
|
||
if (finfo == null)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
String.Format(SR.TypeDoesNotContainRequestedField, typeT.Name, fname));
|
||
}
|
||
DynamicMethod dm = new DynamicMethod("SetObjField",
|
||
typeof(void),
|
||
new Type[] { typeT, typeof(S) },
|
||
typeT);
|
||
ILGenerator ilgen = dm.GetILGenerator();
|
||
ilgen.Emit(OpCodes.Ldarg_0);
|
||
ilgen.Emit(OpCodes.Ldarg_1);
|
||
ilgen.Emit(OpCodes.Stfld, finfo);
|
||
ilgen.Emit(OpCodes.Ret);
|
||
|
||
return (SetObjFieldDelegate<T, S>)dm.CreateDelegate(typeof(SetObjFieldDelegate<T, S>));
|
||
}
|
||
|
||
public static GetStructFieldDelegate<T, S> GetStructField<T, S>(string fname)
|
||
{
|
||
Type typeT = typeof(T);
|
||
if (!typeT.IsValueType)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
SR.CannotBeUsedForReferenceType);
|
||
}
|
||
FieldInfo finfo = typeT.GetField(fname, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
|
||
if (finfo == null)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
String.Format(SR.TypeDoesNotContainRequestedField, typeT.Name, fname));
|
||
}
|
||
DynamicMethod dm = new DynamicMethod("GetStructField",
|
||
typeof(S),
|
||
new Type[] { typeT.MakeByRefType() },
|
||
typeT);
|
||
ILGenerator ilgen = dm.GetILGenerator();
|
||
ilgen.Emit(OpCodes.Ldarg_0);
|
||
ilgen.Emit(OpCodes.Ldfld, finfo);
|
||
ilgen.Emit(OpCodes.Ret);
|
||
|
||
return (GetStructFieldDelegate<T, S>)dm.CreateDelegate(typeof(GetStructFieldDelegate<T, S>));
|
||
}
|
||
|
||
public static SetStructFieldDelegate<T, S> SetStructField<T, S>(string fname)
|
||
{
|
||
Type typeT = typeof(T);
|
||
if (!typeT.IsValueType)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
SR.CannotBeUsedForReferenceType);
|
||
}
|
||
FieldInfo finfo = typeT.GetField(fname, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
|
||
if (finfo == null)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.Internal,
|
||
String.Format(SR.TypeDoesNotContainRequestedField, typeT.Name, fname));
|
||
}
|
||
DynamicMethod dm = new DynamicMethod("SetStructField",
|
||
typeof(void),
|
||
new Type[] { typeT.MakeByRefType(), typeof(S) },
|
||
typeT);
|
||
ILGenerator ilgen = dm.GetILGenerator();
|
||
ilgen.Emit(OpCodes.Ldarg_0);
|
||
ilgen.Emit(OpCodes.Ldarg_1);
|
||
ilgen.Emit(OpCodes.Stfld, finfo);
|
||
ilgen.Emit(OpCodes.Ret);
|
||
|
||
return (SetStructFieldDelegate<T, S>)dm.CreateDelegate(typeof(SetStructFieldDelegate<T, S>));
|
||
}
|
||
}
|
||
}
|