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

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2011-12-01 13:47:21 +0400
committerjfrijters <jfrijters>2011-12-01 13:47:21 +0400
commit8159a8d12c3db9a81774a7c7cb247f93346359ce (patch)
treefe556c5605013f8d0f7b8a51248852b369bca0e3
parenta1709bdbc80521975c606b1f73cd7cf619b6ec63 (diff)
- Added custom modifier support in local variable signatures.
- Fixed SignatureHelper to support custom modifiers in method signatures.
-rw-r--r--reflect/CustomModifiers.cs19
-rw-r--r--reflect/Emit/ILGenerator.cs23
-rw-r--r--reflect/Emit/SignatureHelper.cs9
-rw-r--r--reflect/LocalVariableInfo.cs11
-rw-r--r--reflect/Signature.cs20
5 files changed, 66 insertions, 16 deletions
diff --git a/reflect/CustomModifiers.cs b/reflect/CustomModifiers.cs
index e36029a2..499a120b 100644
--- a/reflect/CustomModifiers.cs
+++ b/reflect/CustomModifiers.cs
@@ -329,5 +329,24 @@ namespace IKVM.Reflection
{
return b == Signature.ELEMENT_TYPE_CMOD_OPT || b == Signature.ELEMENT_TYPE_CMOD_REQD;
}
+
+ internal static CustomModifiers Combine(CustomModifiers mods1, CustomModifiers mods2)
+ {
+ if (mods1.IsEmpty)
+ {
+ return mods2;
+ }
+ else if (mods2.IsEmpty)
+ {
+ return mods1;
+ }
+ else
+ {
+ Type[] combo = new Type[mods1.types.Length + mods2.types.Length];
+ Array.Copy(mods1.types, combo, mods1.types.Length);
+ Array.Copy(mods2.types, 0, combo, mods1.types.Length, mods2.types.Length);
+ return new CustomModifiers(combo);
+ }
+ }
}
}
diff --git a/reflect/Emit/ILGenerator.cs b/reflect/Emit/ILGenerator.cs
index 437a4e3c..46c70918 100644
--- a/reflect/Emit/ILGenerator.cs
+++ b/reflect/Emit/ILGenerator.cs
@@ -152,6 +152,7 @@ namespace IKVM.Reflection.Emit
private readonly ModuleBuilder moduleBuilder;
private readonly ByteBuffer code;
private readonly List<LocalBuilder> locals = new List<LocalBuilder>();
+ private List<CustomModifiers> localCustomModifiers;
private readonly List<int> tokenFixups = new List<int>();
private readonly List<int> labels = new List<int>();
private readonly List<int> labelStackHeight = new List<int>();
@@ -460,6 +461,26 @@ namespace IKVM.Reflection.Emit
return local;
}
+ public LocalBuilder __DeclareLocal(Type localType, bool pinned, CustomModifiers customModifiers)
+ {
+ if (!customModifiers.IsEmpty)
+ {
+ if (localCustomModifiers == null)
+ {
+ localCustomModifiers = new List<CustomModifiers>();
+ }
+ // we lazily fill up the list (to sync with the locals list) and we don't need to
+ // make sure that the list has the same length as the locals list, because
+ // Signature.WriteLocalVarSig() can tolerate that.
+ while (localCustomModifiers.Count < locals.Count)
+ {
+ localCustomModifiers.Add(new CustomModifiers());
+ }
+ localCustomModifiers.Add(customModifiers);
+ }
+ return DeclareLocal(localType, pinned);
+ }
+
public Label DefineLabel()
{
Label label = new Label(labels.Count);
@@ -1034,7 +1055,7 @@ namespace IKVM.Reflection.Emit
if (locals.Count != 0)
{
ByteBuffer localVarSig = new ByteBuffer(locals.Count + 2);
- Signature.WriteLocalVarSig(moduleBuilder, localVarSig, locals);
+ Signature.WriteLocalVarSig(moduleBuilder, localVarSig, locals, localCustomModifiers);
localVarSigTok = 0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(localVarSig));
}
diff --git a/reflect/Emit/SignatureHelper.cs b/reflect/Emit/SignatureHelper.cs
index 8162ef1e..b849371f 100644
--- a/reflect/Emit/SignatureHelper.cs
+++ b/reflect/Emit/SignatureHelper.cs
@@ -162,11 +162,11 @@ namespace IKVM.Reflection.Emit
case 0:
if (unmanaged)
{
- Signature.WriteStandAloneMethodSig(module, bb, __StandAloneMethodSig.Create(unmanagedCallConv, returnType, new CustomModifiers(), args.ToArray(), null));
+ Signature.WriteStandAloneMethodSig(module, bb, __StandAloneMethodSig.Create(unmanagedCallConv, returnType, returnTypeCustomModifiers, args.ToArray(), customModifiers.ToArray()));
}
else
{
- Signature.WriteStandAloneMethodSig(module, bb, __StandAloneMethodSig.Create(callingConvention, returnType, new CustomModifiers(), args.ToArray(), optionalArgs.ToArray(), null));
+ Signature.WriteStandAloneMethodSig(module, bb, __StandAloneMethodSig.Create(callingConvention, returnType, returnTypeCustomModifiers, args.ToArray(), optionalArgs.ToArray(), customModifiers.ToArray()));
}
break;
case Signature.FIELD:
@@ -176,7 +176,7 @@ namespace IKVM.Reflection.Emit
Signature.WritePropertySig(module, bb, callingConvention, returnType, returnTypeCustomModifiers, args.ToArray(), customModifiers.ToArray());
break;
case Signature.LOCAL_SIG:
- Signature.WriteLocalVarSig(module, bb, locals);
+ Signature.WriteLocalVarSig(module, bb, locals, customModifiers);
break;
default:
throw new InvalidOperationException();
@@ -209,7 +209,6 @@ namespace IKVM.Reflection.Emit
{
if (type == Signature.LOCAL_SIG)
{
- // TODO support custom modifiers in local sig
locals.Add(new LocalBuilder(argument, 0, pinned));
}
else if (optional)
@@ -219,8 +218,8 @@ namespace IKVM.Reflection.Emit
else
{
this.args.Add(argument);
- this.customModifiers.Add(customModifiers);
}
+ this.customModifiers.Add(customModifiers);
}
public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
diff --git a/reflect/LocalVariableInfo.cs b/reflect/LocalVariableInfo.cs
index 9575c4f5..e7f05678 100644
--- a/reflect/LocalVariableInfo.cs
+++ b/reflect/LocalVariableInfo.cs
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2009 Jeroen Frijters
+ Copyright (C) 2009-2011 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -30,12 +30,14 @@ namespace IKVM.Reflection
private readonly int index;
private readonly Type type;
private readonly bool pinned;
+ private readonly CustomModifiers customModifiers;
- internal LocalVariableInfo(int index, Type type, bool pinned)
+ internal LocalVariableInfo(int index, Type type, bool pinned, CustomModifiers customModifiers)
{
this.index = index;
this.type = type;
this.pinned = pinned;
+ this.customModifiers = customModifiers;
}
public bool IsPinned
@@ -52,5 +54,10 @@ namespace IKVM.Reflection
{
get { return type; }
}
+
+ public CustomModifiers __GetCustomModifiers()
+ {
+ return customModifiers;
+ }
}
}
diff --git a/reflect/Signature.cs b/reflect/Signature.cs
index d4e0d2ad..ac93a3c3 100644
--- a/reflect/Signature.cs
+++ b/reflect/Signature.cs
@@ -259,20 +259,20 @@ namespace IKVM.Reflection
if (br.PeekByte() == ELEMENT_TYPE_TYPEDBYREF)
{
br.ReadByte();
- list.Add(new LocalVariableInfo(i, module.universe.System_TypedReference, false));
+ list.Add(new LocalVariableInfo(i, module.universe.System_TypedReference, false, new CustomModifiers()));
}
else
{
- CustomModifiers.Skip(br);
+ CustomModifiers mods1 = CustomModifiers.Read(module, br, context);
bool pinned = false;
if (br.PeekByte() == ELEMENT_TYPE_PINNED)
{
br.ReadByte();
pinned = true;
}
- CustomModifiers.Skip(br);
+ CustomModifiers mods2 = CustomModifiers.Read(module, br, context);
Type type = ReadTypeOrByRef(module, br, context);
- list.Add(new LocalVariableInfo(i, type, pinned));
+ list.Add(new LocalVariableInfo(i, type, pinned, CustomModifiers.Combine(mods1, mods2)));
}
}
}
@@ -585,17 +585,21 @@ namespace IKVM.Reflection
}
}
- internal static void WriteLocalVarSig(ModuleBuilder module, ByteBuffer bb, IList<LocalBuilder> locals)
+ internal static void WriteLocalVarSig(ModuleBuilder module, ByteBuffer bb, IList<LocalBuilder> locals, IList<CustomModifiers> customModifiers)
{
bb.Write(LOCAL_SIG);
bb.WriteCompressedInt(locals.Count);
- foreach (LocalBuilder local in locals)
+ for (int i = 0; i < locals.Count; i++)
{
- if (local.IsPinned)
+ if (locals[i].IsPinned)
{
bb.Write(ELEMENT_TYPE_PINNED);
}
- WriteType(module, bb, local.LocalType);
+ if (customModifiers != null && i < customModifiers.Count)
+ {
+ WriteCustomModifiers(module, bb, customModifiers[i]);
+ }
+ WriteType(module, bb, locals[i].LocalType);
}
}