static int typespec_tokengen = 0x1bffffff;
static int memberref_tokengen = 0x0affffff;
static int methoddef_tokengen = 0x06ffffff;
- Dictionary<MemberInfo, int> inst_tokens = new Dictionary<MemberInfo, int> ();
- Dictionary<MemberInfo, int> inst_tokens_open = new Dictionary<MemberInfo, int> ();
+ Dictionary<MemberInfo, int> inst_tokens, inst_tokens_open;
//
// Assign a pseudo token to the various TypeBuilderInst objects, so the runtime
// still encounter these objects, it will resolve them by calling their
// RuntimeResolve () methods.
//
- int GetPseudoToken (MemberInfo member, bool create_open_instance) {
+ int GetPseudoToken (MemberInfo member, bool create_open_instance)
+ {
int token;
-
- if (create_open_instance) {
- if (inst_tokens_open.TryGetValue (member, out token))
- return token;
- } else {
- if (inst_tokens.TryGetValue (member, out token))
- return token;
+ var dict = create_open_instance ? inst_tokens_open : inst_tokens;
+ if (dict == null) {
+ dict = new Dictionary<MemberInfo, int> (ReferenceEqualityComparer<MemberInfo>.Instance);
+ if (create_open_instance)
+ inst_tokens_open = dict;
+ else
+ inst_tokens = dict;
+ } else if (dict.TryGetValue (member, out token)) {
+ return token;
}
+
// Count backwards to avoid collisions with the tokens
// allocated by the runtime
if (member is TypeBuilderInstantiation || member is SymbolType)
token = typespec_tokengen --;
} else
throw new NotImplementedException ();
- if (create_open_instance)
- inst_tokens_open [member] = token;
- else
- inst_tokens [member] = token;
+
+ dict [member] = token;
RegisterToken (member, token);
return token;
}
//
// Fixup the pseudo tokens assigned to the various SRE objects
//
- void FixupTokens () {
+ void FixupTokens ()
+ {
var token_map = new Dictionary<int, int> ();
var member_map = new Dictionary<int, MemberInfo> ();
- FixupTokens (token_map, member_map, inst_tokens, false);
- FixupTokens (token_map, member_map, inst_tokens_open, true);
+ if (inst_tokens != null)
+ FixupTokens (token_map, member_map, inst_tokens, false);
+ if (inst_tokens_open != null)
+ FixupTokens (token_map, member_map, inst_tokens_open, true);
// Replace the tokens in the IL stream
if (types != null) {
}
}
+ [Test]
+ public void TestEnumWithLateUnderlyingField ()
+ {
+ TypeBuilder enumToCreate = module.DefineType (genTypeName (), TypeAttributes.Public, typeof (Enum));
+ enumToCreate.DefineField ("value__", typeof (Int32),
+ FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
+
+ TypeBuilder enumToCreate2 = module.DefineType (genTypeName (), TypeAttributes.Public, typeof (Enum));
+
+ TypeBuilder ivTypeBld = module.DefineType (genTypeName (), TypeAttributes.Public);
+
+ ConstructorBuilder ivCtor = ivTypeBld.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
+
+ ILGenerator ctorIL = ivCtor.GetILGenerator ();
+
+ ctorIL.Emit (OpCodes.Ldtoken, typeof (Object));
+ ctorIL.Emit (OpCodes.Pop);
+ ctorIL.Emit (OpCodes.Ldtoken, enumToCreate);
+ ctorIL.Emit (OpCodes.Pop);
+ ctorIL.Emit (OpCodes.Ldtoken, enumToCreate2);
+ ctorIL.Emit (OpCodes.Pop);
+ ctorIL.Emit (OpCodes.Ret);
+
+ var ivType = ivTypeBld.CreateType ();
+
+ enumToCreate2.DefineField ("value__", typeof (Int32), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
+
+ FieldBuilder fb = enumToCreate2.DefineField ("A", enumToCreate, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
+ fb.SetConstant (0);
+
+ enumToCreate.CreateType ();
+ enumToCreate2.CreateType ();
+ }
+
[Test]
public void TestIsAbstract ()
{