Пример #1
0
 internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags)
 {
     if (i >= 3
         && (flags[i - 0] & InstructionFlags.BranchTarget) == 0
         && (flags[i - 1] & InstructionFlags.BranchTarget) == 0
         && (flags[i - 2] & InstructionFlags.BranchTarget) == 0
         && (flags[i - 3] & InstructionFlags.BranchTarget) == 0
         && code[i - 1].NormalizedOpCode == NormalizedByteCode.__ldc
         && code[i - 2].NormalizedOpCode == NormalizedByteCode.__ldc
         && code[i - 3].NormalizedOpCode == NormalizedByteCode.__ldc)
     {
         // we now have a structural match, now we need to make sure that the argument values are what we expect
         TypeWrapper tclass = classFile.GetConstantPoolClassType(code[i - 3].Arg1);
         TypeWrapper vclass = classFile.GetConstantPoolClassType(code[i - 2].Arg1);
         string fieldName = classFile.GetConstantPoolConstantString(code[i - 1].Arg1);
         if (tclass == wrapper && !vclass.IsUnloadable && !vclass.IsPrimitive && !vclass.IsNonPrimitiveValueType)
         {
             FieldWrapper field = wrapper.GetFieldWrapper(fieldName, vclass.SigName);
             if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass)
             {
                 // everything matches up, now call the actual emitter
                 DoEmit(context, wrapper, ilgen, field);
                 return true;
             }
         }
     }
     return false;
 }
Пример #2
0
 /// <summary>
 /// Resolve this reference.
 /// </summary>
 public bool TryResolveClass(out ClassFile result)
 {
     if (resolvedClass == null)
     {
         DoTryResolveClass(out resolvedClass);
     }
     result = resolvedClass;
     return (result != null);
 }
Пример #3
0
 /// <summary>
 /// Resolve this reference.
 /// </summary>
 public bool TryResolve(out ClassFile result)
 {
     if (resolved == null)
     {
         var type = Type as ObjectTypeReference;
         if (type != null)
         {
             Loader.TryLoadClass(Name, out resolved);
         }
     }
     result = resolved;
     return (result != null);
 }
Пример #4
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        protected virtual void CreateClassDefinition(Dex target, NameConverter nsConverter, ClassDefinition parent, ClassFile parentClass)
        {
            // Create classdef
            classDef           = new ClassDefinition();
            classDef.MapFileId = compiler.GetNextMapFileId();
            classDef.Namespace = nsConverter.GetConvertedNamespace(typeDef);
            var name = NameConverter.GetConvertedName(typeDef);

            classDef.Name = (parent != null) ? parent.Name + "$" + name : name;

            // Set access flags
            //if (typeDef.IsPublic) classDef.IsPublic = true;
            //else classDef.IsPrivate = true;
            classDef.IsPublic = true;
            if (typeDef.IsFinal)
            {
                classDef.IsFinal = true;
            }
            if (typeDef.IsInterface)
            {
                classDef.IsInterface = true;
                classDef.IsAbstract  = true;
            }
            else if (typeDef.IsAbstract)
            {
                classDef.IsAbstract = true;
            }
            if (typeDef.Interfaces.Any(x => x.ClassName == "java/lang/annotation/Annotation"))
            {
                classDef.IsAnnotation = true;
            }

            classDef.IsEnum = typeDef.IsEnum;

            if (parent != null)
            {
                // Add to parent if this is a nested type
                classDef.Owner = parent;
                parent.AddInnerClass(classDef);
            }
            else
            {
                // Add to dex if it is a root class
                target.AddClass(classDef);
            }
        }
Пример #5
0
 /// <summary>
 /// Create the current type as class definition.
 /// </summary>
 protected void Create(Dex target, NameConverter nsConverter, ClassDefinition parent, ClassFile parentClass, XTypeDefinition parentXType)
 {
     xType = new XBuilder.JavaTypeDefinition(compiler.Module, parentXType, typeDef);
     CreateClassDefinition(target, nsConverter, parent, parentClass);
     CreateNestedClasses(target, nsConverter, parent);
 }
Пример #6
0
			protected abstract void ValidateSig(ClassFile classFile, string descriptor);
Пример #7
0
			protected override void ValidateSig(ClassFile classFile, string descriptor)
			{
				if(!IsValidMethodSig(descriptor))
				{
					throw new ClassFormatError("{0} (Method \"{1}\" has invalid signature \"{2}\")", classFile.Name, this.Name, descriptor);
				}
			}
Пример #8
0
			internal virtual void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
			}
Пример #9
0
			internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
				string descriptor = classFile.GetConstantPoolUtf8String(utf8_cp, signature_index);
				if (descriptor == null || !IsValidMethodSig(descriptor))
				{
					throw new ClassFormatError("Invalid MethodType signature");
				}
				this.descriptor = String.Intern(descriptor.Replace('/', '.'));
			}
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangReflectConstructorBuilder(ClassFile cf)
     : base(cf, "System.Reflection.ConstructorInfo", "java/lang/reflect/Constructor")
 {
 }
Пример #11
0
	private static Dictionary<int, string>[] FindLocalVariables(CodeInfo codeInfo, MethodWrapper mw, ClassFile classFile, ClassFile.Method method)
	{
		FindLocalVarState[] state = new FindLocalVarState[method.Instructions.Length];
		state[0].changed = true;
		state[0].sites = new FindLocalVarStoreSite[method.MaxLocals];
		TypeWrapper[] parameters = mw.GetParameters();
		int argpos = 0;
		if (!mw.IsStatic)
		{
			state[0].sites[argpos++].Add(-1);
		}
		for (int i = 0; i < parameters.Length; i++)
		{
			state[0].sites[argpos++].Add(-1);
			if (parameters[i].IsWidePrimitive)
			{
				argpos++;
			}
		}
		return FindLocalVariablesImpl(codeInfo, classFile, method, state);
	}
Пример #12
0
 protected override void CreateNestedTypes(ClassFile cf, Model.NetTypeDefinition declaringType, string parentFullName, Model.NetModule module, TargetFramework target)
 {
     // Do nothing
 }
Пример #13
0
 /// <summary>
 /// Create type attributes
 /// </summary>
 protected override TypeAttributes GetAttributes(ClassFile cf)
 {
     return(TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract);
 }
Пример #14
0
 protected override void RegisterType(TargetFramework target, ClassFile classFile, Model.NetTypeDefinition typeDef)
 {
     // Do nothing
 }
Пример #15
0
 /// <summary>
 /// Improve the type name for the given class.
 /// </summary>
 protected override string CreateTypeName(NetTypeDefinition declaringType, ClassFile classFile, string name, string @namespace)
 {
     return(base.CreateTypeName(declaringType, classFile, name, @namespace) + "Constants");
 }
Пример #16
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public NestedInterfaceConstantsTypeBuilder(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner)
     : base(parent, parentFullName, cf, inner)
 {
 }
Пример #17
0
 public static long timestamp( ClassFile file )
 {
     Bard.log( "TODO: NativeFile::timestamp()" );
       return 0;
 }
Пример #18
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangNoSuchFieldExceptionBuilder(ClassFile cf)
     : base(cf, "System.MissingFieldException", "java/lang/NoSuchFieldError")
 {
 }
Пример #19
0
 public static java.lang.Class defineClass1(java.lang.ClassLoader thisClassLoader, string name, byte[] b, int off, int len, java.security.ProtectionDomain pd, string source)
 {
     // it appears the source argument is only used for trace messages in HotSpot. We'll just ignore it for now.
     Profiler.Enter("ClassLoader.defineClass");
     try
     {
         try
         {
             ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(thisClassLoader);
             ClassFile classFile = new ClassFile(b, off, len, name, classLoaderWrapper.ClassFileParseOptions, null);
             if (name != null && classFile.Name != name)
             {
     #if !FIRST_PASS
                 throw new java.lang.NoClassDefFoundError(name + " (wrong name: " + classFile.Name + ")");
     #endif
             }
             TypeWrapper type = classLoaderWrapper.DefineClass(classFile, pd);
             return type.ClassObject;
         }
         catch (RetargetableJavaException x)
         {
             throw x.ToJava();
         }
     }
     finally
     {
         Profiler.Leave("ClassLoader.defineClass");
     }
 }
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangComparableBuilder(ClassFile cf)
     : base(cf, "System.Comparable", "java/lang/Comparable")
 {
 }
Пример #21
0
	private static void VisitLocalLoads(CodeInfo codeInfo, ClassFile.Method method, List<LocalVar> locals, Dictionary<long, LocalVar> localByStoreSite, Dictionary<int, string> storeSites, int instructionIndex, bool debug)
	{
		Debug.Assert(IsLoadLocal(method.Instructions[instructionIndex].NormalizedOpCode));
		LocalVar local = null;
		TypeWrapper type = VerifierTypeWrapper.Null;
		int localIndex = method.Instructions[instructionIndex].NormalizedArg1;
		bool isArg = false;
		foreach (int store in storeSites.Keys)
		{
			if (store == -1)
			{
				// it's a method argument, it has no initial store, but the type is simply the parameter type
				type = InstructionState.FindCommonBaseType(type, codeInfo.GetLocalTypeWrapper(0, localIndex));
				isArg = true;
			}
			else
			{
				if (method.Instructions[store].NormalizedOpCode == NormalizedByteCode.__invokespecial)
				{
					type = InstructionState.FindCommonBaseType(type, codeInfo.GetLocalTypeWrapper(store + 1, localIndex));
				}
				else if (method.Instructions[store].NormalizedOpCode == NormalizedByteCode.__static_error)
				{
					// it's an __invokespecial that turned into a __static_error
					// (since a __static_error doesn't continue, we don't need to set type)
				}
				else
				{
					Debug.Assert(IsStoreLocal(method.Instructions[store].NormalizedOpCode));
					type = InstructionState.FindCommonBaseType(type, codeInfo.GetStackTypeWrapper(store, 0));
				}
			}
			// we can't have an invalid type, because that would have failed verification earlier
			Debug.Assert(type != VerifierTypeWrapper.Invalid);

			LocalVar l;
			if (localByStoreSite.TryGetValue(MakeKey(store, localIndex), out l))
			{
				if (local == null)
				{
					local = l;
				}
				else if (local != l)
				{
					// If we've already defined a LocalVar and we find another one, then we merge them
					// together.
					// This happens for the following code fragment:
					//
					// int i = -1;
					// try { i = 0; for(; ; ) System.out.println(i); } catch(Exception x) {}
					// try { i = 0; for(; ; ) System.out.println(i); } catch(Exception x) {}
					// System.out.println(i);
					//
					local = MergeLocals(locals, localByStoreSite, local, l);
				}
			}
		}
		if (local == null)
		{
			local = new LocalVar();
			local.local = localIndex;
			if (VerifierTypeWrapper.IsThis(type))
			{
				local.type = ((VerifierTypeWrapper)type).UnderlyingType;
			}
			else
			{
				local.type = type;
			}
			local.isArg = isArg;
			if (debug)
			{
				FindLvtEntry(local, method, instructionIndex);
			}
			locals.Add(local);
		}
		else
		{
			local.isArg |= isArg;
			local.type = InstructionState.FindCommonBaseType(local.type, type);
			Debug.Assert(local.type != VerifierTypeWrapper.Invalid);
		}
		foreach (int store in storeSites.Keys)
		{
			LocalVar v;
			if (!localByStoreSite.TryGetValue(MakeKey(store, localIndex), out v))
			{
				localByStoreSite[MakeKey(store, localIndex)] = local;
			}
			else if (v != local)
			{
				local = MergeLocals(locals, localByStoreSite, local, v);
			}
		}
	}
Пример #22
0
 protected override string GetContent(Task task, ClassFile classFile)
 {
     return(Dao.Factory.ClassFileDao.GivenTypesFileContents(task, classFile));
 }
Пример #23
0
			internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
				if(classFile.GetConstantPoolUtf8String(utf8_cp, name_index) == null
					|| classFile.GetConstantPoolUtf8String(utf8_cp, descriptor_index) == null)
				{
					throw new ClassFormatError("Illegal constant pool index");
				}
			}
Пример #24
0
 public GivenTypeFile(Task parent, ClassFile source) : base(parent, source)
 {
 }
Пример #25
0
			internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
				s = classFile.GetConstantPoolUtf8String(utf8_cp, string_index);
			}
Пример #26
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangFloatBuilder(ClassFile cf)
     : base(cf, "System.Single", "java/lang/Float")
 {
 }
Пример #27
0
			private void DecodePropertyAnnotation(ClassFile classFile, object[] annot)
			{
				if(propertyGetterSetter != null)
				{
					Tracer.Error(Tracer.ClassLoading, "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}", classFile.Name, this.Name);
					return;
				}
				propertyGetterSetter = new string[2];
				for(int i = 2; i < annot.Length - 1; i += 2)
				{
					string value = annot[i + 1] as string;
					if(value == null)
					{
						propertyGetterSetter = null;
						break;
					}
					if(annot[i].Equals("get") && propertyGetterSetter[0] == null)
					{
						propertyGetterSetter[0] = value;
					}
					else if(annot[i].Equals("set") && propertyGetterSetter[1] == null)
					{
						propertyGetterSetter[1] = value;
					}
					else
					{
						propertyGetterSetter = null;
						break;
					}
				}
				if(propertyGetterSetter == null || propertyGetterSetter[0] == null)
				{
					propertyGetterSetter = null;
					Tracer.Error(Tracer.ClassLoading, "Ignoring malformed ikvm.lang.Property annotation on {0}.{1}", classFile.Name, this.Name);
					return;
				}
			}
Пример #28
0
 /// <summary>
 /// Create a type builder for the given type.
 /// </summary>
 internal static ClassBuilder Create(AssemblyCompiler compiler, ClassFile typeDef)
 {
     return(new StandardClassBuilder(compiler, typeDef));
 }
Пример #29
0
				internal void Read(ushort pc, BigEndianBinaryReader br, ClassFile classFile)
				{
					this.pc = pc;
					ByteCode bc = (ByteCode)br.ReadByte();
					switch(ByteCodeMetaData.GetMode(bc))
					{
						case ByteCodeMode.Simple:
							break;
						case ByteCodeMode.Constant_1:
							arg1 = br.ReadByte();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							break;
						case ByteCodeMode.Local_1:
							arg1 = br.ReadByte();
							break;
						case ByteCodeMode.Constant_2:
							arg1 = br.ReadUInt16();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							break;
						case ByteCodeMode.Branch_2:
							arg1 = br.ReadInt16();
							break;
						case ByteCodeMode.Branch_4:
							arg1 = br.ReadInt32();
							break;
						case ByteCodeMode.Constant_2_1_1:
							arg1 = br.ReadUInt16();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							arg2 = br.ReadByte();
							if(br.ReadByte() != 0)
							{
								throw new ClassFormatError("invokeinterface filler must be zero");
							}
							break;
						case ByteCodeMode.Immediate_1:
							arg1 = br.ReadSByte();
							break;
						case ByteCodeMode.Immediate_2:
							arg1 = br.ReadInt16();
							break;
						case ByteCodeMode.Local_1_Immediate_1:
							arg1 = br.ReadByte();
							arg2 = br.ReadSByte();
							break;
						case ByteCodeMode.Constant_2_Immediate_1:
							arg1 = br.ReadUInt16();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							arg2 = br.ReadSByte();
							break;
						case ByteCodeMode.Tableswitch:
						{
							// skip the padding
							uint p = pc + 1u;
							uint align = ((p + 3) & 0x7ffffffc) - p;
							br.Skip(align);
							int default_offset = br.ReadInt32();
							this.arg1 = default_offset;
							int low = br.ReadInt32();
							int high = br.ReadInt32();
							if(low > high || high > 16384L + low)
							{
								throw new ClassFormatError("Incorrect tableswitch");
							}
							SwitchEntry[] entries = new SwitchEntry[high - low + 1];
							for(int i = low; i < high; i++)
							{
								entries[i - low].value = i;
								entries[i - low].target = br.ReadInt32();
							}
							// do the last entry outside the loop, to avoid overflowing "i", if high == int.MaxValue
							entries[high - low].value = high;
							entries[high - low].target = br.ReadInt32();
							this.switch_entries = entries;
							break;
						}
						case ByteCodeMode.Lookupswitch:
						{
							// skip the padding
							uint p = pc + 1u;
							uint align = ((p + 3) & 0x7ffffffc) - p;
							br.Skip(align);
							int default_offset = br.ReadInt32();
							this.arg1 = default_offset;
							int count = br.ReadInt32();
							if(count < 0 || count > 16384)
							{
								throw new ClassFormatError("Incorrect lookupswitch");
							}
							SwitchEntry[] entries = new SwitchEntry[count];
							for(int i = 0; i < count; i++)
							{
								entries[i].value = br.ReadInt32();
								entries[i].target = br.ReadInt32();
							}
							this.switch_entries = entries;
							break;
						}
						case ByteCodeMode.WidePrefix:
							bc = (ByteCode)br.ReadByte();
							// NOTE the PC of a wide instruction is actually the PC of the
							// wide prefix, not the following instruction (vmspec 4.9.2)
						switch(ByteCodeMetaData.GetWideMode(bc))
						{
							case ByteCodeModeWide.Local_2:
								arg1 = br.ReadUInt16();
								break;
							case ByteCodeModeWide.Local_2_Immediate_2:
								arg1 = br.ReadUInt16();
								arg2 = br.ReadInt16();
								break;
							default:
								throw new ClassFormatError("Invalid wide prefix on opcode: {0}", bc);
						}
							break;
						default:
							throw new ClassFormatError("Invalid opcode: {0}", bc);
					}
					this.normopcode = ByteCodeMetaData.GetNormalizedByteCode(bc);
					arg1 = ByteCodeMetaData.GetArg(bc, arg1);
				}
Пример #30
0
 public static void native_mkdir( ClassFile file )
 {
     Bard.log( "TODO: NativeFile::native_mkdir()" );
 }
Пример #31
0
    private static Dictionary <int, string>[] FindLocalVariables(CodeInfo codeInfo, MethodWrapper mw, ClassFile classFile, ClassFile.Method method)
    {
        FindLocalVarState[] state = new FindLocalVarState[method.Instructions.Length];
        state[0].changed = true;
        state[0].sites   = new FindLocalVarStoreSite[method.MaxLocals];
        TypeWrapper[] parameters = mw.GetParameters();
        int           argpos     = 0;

        if (!mw.IsStatic)
        {
            state[0].sites[argpos++].Add(-1);
        }
        for (int i = 0; i < parameters.Length; i++)
        {
            state[0].sites[argpos++].Add(-1);
            if (parameters[i].IsWidePrimitive)
            {
                argpos++;
            }
        }
        return(FindLocalVariablesImpl(codeInfo, classFile, method, state));
    }
Пример #32
0
 /// <summary>
 /// Default ctor
 /// </summary>
 protected ClassBuilder(AssemblyCompiler compiler, ClassFile typeDef)
 {
     this.compiler = compiler;
     this.typeDef  = typeDef;
 }
Пример #33
0
 public static bool is_directory( ClassFile file )
 {
     Bard.log( "TODO: NativeFile::is_directory()" );
       return false;
 }
Пример #34
0
    private static Dictionary <int, string>[] FindLocalVariablesImpl(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, FindLocalVarState[] state)
    {
        ClassFile.Method.Instruction[] instructions = method.Instructions;
        ExceptionTableEntry[]          exceptions   = method.ExceptionTable;
        int maxLocals = method.MaxLocals;

        Dictionary <int, string>[] localStoreReaders = new Dictionary <int, string> [instructions.Length];
        bool done = false;

        while (!done)
        {
            done = true;
            for (int i = 0; i < instructions.Length; i++)
            {
                if (state[i].changed)
                {
                    done             = false;
                    state[i].changed = false;

                    FindLocalVarState curr = state[i].Copy();

                    for (int j = 0; j < exceptions.Length; j++)
                    {
                        if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
                        {
                            state[exceptions[j].handlerIndex].Merge(curr);
                        }
                    }

                    if (IsLoadLocal(instructions[i].NormalizedOpCode) &&
                        (instructions[i].NormalizedOpCode != NormalizedByteCode.__aload || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i + 1, 0))))
                    {
                        if (localStoreReaders[i] == null)
                        {
                            localStoreReaders[i] = new Dictionary <int, string>();
                        }
                        for (int j = 0; j < curr.sites[instructions[i].NormalizedArg1].Count; j++)
                        {
                            localStoreReaders[i][curr.sites[instructions[i].NormalizedArg1][j]] = "";
                        }
                    }

                    if (IsStoreLocal(instructions[i].NormalizedOpCode) &&
                        (instructions[i].NormalizedOpCode != NormalizedByteCode.__astore || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i, 0))))
                    {
                        curr.Store(i, instructions[i].NormalizedArg1);
                        // if this is a store at the end of an exception block,
                        // we need to propagate the new state to the exception handler
                        for (int j = 0; j < exceptions.Length; j++)
                        {
                            if (exceptions[j].endIndex == i + 1)
                            {
                                state[exceptions[j].handlerIndex].Merge(curr);
                            }
                        }
                    }

                    if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
                    {
                        ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instructions[i].Arg1);
                        if (ReferenceEquals(cpi.Name, StringConstants.INIT))
                        {
                            TypeWrapper type = codeInfo.GetRawStackTypeWrapper(i, cpi.GetArgTypes().Length);
                            // after we've invoked the constructor, the uninitialized references
                            // are now initialized
                            if (type == VerifierTypeWrapper.UninitializedThis ||
                                VerifierTypeWrapper.IsNew(type))
                            {
                                for (int j = 0; j < maxLocals; j++)
                                {
                                    if (codeInfo.GetLocalTypeWrapper(i, j) == type)
                                    {
                                        curr.Store(i, j);
                                    }
                                }
                            }
                        }
                    }
                    else if (instructions[i].NormalizedOpCode == NormalizedByteCode.__goto_finally)
                    {
                        int handler = instructions[i].HandlerIndex;

                        // Normally a store at the end of a try block doesn't affect the handler block,
                        // but in the case of a finally handler it does, so we need to make sure that
                        // we merge here in case the try block ended with a store.
                        state[handler].Merge(curr);

                        // Now we recursively analyse the handler and afterwards merge the endfault locations back to us
                        FindLocalVarState[] handlerState = new FindLocalVarState[instructions.Length];
                        handlerState[handler].Merge(curr);
                        curr = new FindLocalVarState();
                        FindLocalVariablesImpl(codeInfo, classFile, method, handlerState);

                        // Merge back to the target of our __goto_finally
                        for (int j = 0; j < handlerState.Length; j++)
                        {
                            if (instructions[j].NormalizedOpCode == NormalizedByteCode.__athrow &&
                                codeInfo.HasState(j) &&
                                VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0)) &&
                                ((VerifierTypeWrapper)codeInfo.GetRawStackTypeWrapper(j, 0)).Index == handler)
                            {
                                curr.Merge(handlerState[j]);
                            }
                        }
                    }

                    switch (ByteCodeMetaData.GetFlowControl(instructions[i].NormalizedOpCode))
                    {
                    case ByteCodeFlowControl.Switch:
                    {
                        for (int j = 0; j < instructions[i].SwitchEntryCount; j++)
                        {
                            state[instructions[i].GetSwitchTargetIndex(j)].Merge(curr);
                        }
                        state[instructions[i].DefaultTarget].Merge(curr);
                        break;
                    }

                    case ByteCodeFlowControl.Branch:
                        state[instructions[i].TargetIndex].Merge(curr);
                        break;

                    case ByteCodeFlowControl.CondBranch:
                        state[instructions[i].TargetIndex].Merge(curr);
                        state[i + 1].Merge(curr);
                        break;

                    case ByteCodeFlowControl.Return:
                    case ByteCodeFlowControl.Throw:
                        break;

                    case ByteCodeFlowControl.Next:
                        state[i + 1].Merge(curr);
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }
            }
        }
        return(localStoreReaders);
    }
Пример #35
0
 public static void rename( ClassFile file, ClassString new_name )
 {
     Bard.log( "TODO: NativeFile::rename()" );
 }
Пример #36
0
    internal LocalVarInfo(CodeInfo ma, ClassFile classFile, ClassFile.Method method, UntangledExceptionTable exceptions, MethodWrapper mw, ClassLoaderWrapper classLoader)
    {
        Dictionary <int, string>[] localStoreReaders = FindLocalVariables(ma, mw, classFile, method);

        // now that we've done the code flow analysis, we can do a liveness analysis on the local variables
        ClassFile.Method.Instruction[] instructions     = method.Instructions;
        Dictionary <long, LocalVar>    localByStoreSite = new Dictionary <long, LocalVar>();
        List <LocalVar> locals = new List <LocalVar>();

        for (int i = 0; i < localStoreReaders.Length; i++)
        {
            if (localStoreReaders[i] != null)
            {
                VisitLocalLoads(ma, method, locals, localByStoreSite, localStoreReaders[i], i, classLoader.EmitDebugInfo);
            }
        }
        Dictionary <LocalVar, LocalVar> forwarders = new Dictionary <LocalVar, LocalVar>();

        if (classLoader.EmitDebugInfo)
        {
            InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(ma, method.Instructions, exceptions, 0, false);
            // if we're emitting debug info, we need to keep dead stores as well...
            for (int i = 0; i < instructions.Length; i++)
            {
                if ((flags[i] & InstructionFlags.Reachable) != 0 &&
                    IsStoreLocal(instructions[i].NormalizedOpCode))
                {
                    if (!localByStoreSite.ContainsKey(MakeKey(i, instructions[i].NormalizedArg1)))
                    {
                        LocalVar v = new LocalVar();
                        v.local = instructions[i].NormalizedArg1;
                        v.type  = ma.GetStackTypeWrapper(i, 0);
                        FindLvtEntry(v, method, i);
                        locals.Add(v);
                        localByStoreSite.Add(MakeKey(i, v.local), v);
                    }
                }
            }
            // to make the debugging experience better, we have to trust the
            // LocalVariableTable (unless it's clearly bogus) and merge locals
            // together that are the same according to the LVT
            for (int i = 0; i < locals.Count - 1; i++)
            {
                for (int j = i + 1; j < locals.Count; j++)
                {
                    LocalVar v1 = (LocalVar)locals[i];
                    LocalVar v2 = (LocalVar)locals[j];
                    if (v1.name != null && v1.name == v2.name && v1.start_pc == v2.start_pc && v1.end_pc == v2.end_pc)
                    {
                        // we can only merge if the resulting type is valid (this protects against incorrect
                        // LVT data, but is also needed for constructors, where the uninitialized this is a different
                        // type from the initialized this)
                        TypeWrapper tw = InstructionState.FindCommonBaseType(v1.type, v2.type);
                        if (tw != VerifierTypeWrapper.Invalid)
                        {
                            v1.isArg |= v2.isArg;
                            v1.type   = tw;
                            forwarders.Add(v2, v1);
                            locals.RemoveAt(j);
                            j--;
                        }
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < locals.Count - 1; i++)
            {
                for (int j = i + 1; j < locals.Count; j++)
                {
                    LocalVar v1 = (LocalVar)locals[i];
                    LocalVar v2 = (LocalVar)locals[j];
                    // if the two locals are the same, we merge them, this is a small
                    // optimization, it should *not* be required for correctness.
                    if (v1.local == v2.local && v1.type == v2.type)
                    {
                        v1.isArg |= v2.isArg;
                        forwarders.Add(v2, v1);
                        locals.RemoveAt(j);
                        j--;
                    }
                }
            }
        }
        invokespecialLocalVars = new LocalVar[instructions.Length][];
        localVars = new LocalVar[instructions.Length];
        for (int i = 0; i < localVars.Length; i++)
        {
            LocalVar v = null;
            if (localStoreReaders[i] != null)
            {
                Debug.Assert(IsLoadLocal(instructions[i].NormalizedOpCode));
                // lame way to look up the local variable for a load
                // (by indirecting through a corresponding store)
                foreach (int store in localStoreReaders[i].Keys)
                {
                    v = localByStoreSite[MakeKey(store, instructions[i].NormalizedArg1)];
                    break;
                }
            }
            else
            {
                if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial || instructions[i].NormalizedOpCode == NormalizedByteCode.__dynamic_invokespecial)
                {
                    invokespecialLocalVars[i] = new LocalVar[method.MaxLocals];
                    for (int j = 0; j < invokespecialLocalVars[i].Length; j++)
                    {
                        localByStoreSite.TryGetValue(MakeKey(i, j), out invokespecialLocalVars[i][j]);
                    }
                }
                else
                {
                    localByStoreSite.TryGetValue(MakeKey(i, instructions[i].NormalizedArg1), out v);
                }
            }
            if (v != null)
            {
                LocalVar fwd;
                if (forwarders.TryGetValue(v, out fwd))
                {
                    v = fwd;
                }
                localVars[i] = v;
            }
        }
        this.allLocalVars = locals.ToArray();
    }
Пример #37
0
 public static void touch( ClassFile file )
 {
     Bard.log( "TODO: NativeFile::touch()" );
 }
Пример #38
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangClassBuilder(ClassFile cf)
     : base(cf, "System.Type", "java/lang/Class")
 {
 }
Пример #39
0
	private static void FindLvtEntry(LocalVar lv, ClassFile.Method method, int instructionIndex)
	{
		ClassFile.Method.LocalVariableTableEntry[] lvt = method.LocalVariableTableAttribute;
		if (lvt != null)
		{
			int pc = method.Instructions[instructionIndex].PC;
			int nextPC = method.Instructions[instructionIndex + 1].PC;
			bool isStore = IsStoreLocal(method.Instructions[instructionIndex].NormalizedOpCode);
			foreach (ClassFile.Method.LocalVariableTableEntry e in lvt)
			{
				// TODO validate the contents of the LVT entry
				if (e.index == lv.local &&
					(e.start_pc <= pc || (e.start_pc == nextPC && isStore)) &&
					e.start_pc + e.length > pc)
				{
					lv.name = e.name;
					lv.start_pc = e.start_pc;
					lv.end_pc = e.start_pc + e.length;
					break;
				}
			}
		}
	}
Пример #40
0
 protected virtual void AddGenericRepositoryParameter(ClassFile classFile)
 {
     classFile.Constructor.AddFieldWithParameter(new Field("private", "_genericRepository", $"IGenericRepository<{GetEntityName}>"), new TypeWithName("genericRepository", $"IGenericRepository<{GetEntityName}>"));
 }
Пример #41
0
	private static Dictionary<int, string>[] FindLocalVariablesImpl(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, FindLocalVarState[] state)
	{
		ClassFile.Method.Instruction[] instructions = method.Instructions;
		ExceptionTableEntry[] exceptions = method.ExceptionTable;
		int maxLocals = method.MaxLocals;
		Dictionary<int, string>[] localStoreReaders = new Dictionary<int, string>[instructions.Length];
		bool done = false;

		while (!done)
		{
			done = true;
			for (int i = 0; i < instructions.Length; i++)
			{
				if (state[i].changed)
				{
					done = false;
					state[i].changed = false;

					FindLocalVarState curr = state[i].Copy();

					for (int j = 0; j < exceptions.Length; j++)
					{
						if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
						{
							state[exceptions[j].handlerIndex].Merge(curr);
						}
					}

					if (IsLoadLocal(instructions[i].NormalizedOpCode)
						&& (instructions[i].NormalizedOpCode != NormalizedByteCode.__aload || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i + 1, 0))))
					{
						if (localStoreReaders[i] == null)
						{
							localStoreReaders[i] = new Dictionary<int, string>();
						}
						for (int j = 0; j < curr.sites[instructions[i].NormalizedArg1].Count; j++)
						{
							localStoreReaders[i][curr.sites[instructions[i].NormalizedArg1][j]] = "";
						}
					}

					if (IsStoreLocal(instructions[i].NormalizedOpCode)
						&& (instructions[i].NormalizedOpCode != NormalizedByteCode.__astore || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i, 0))))
					{
						curr.Store(i, instructions[i].NormalizedArg1);
						// if this is a store at the end of an exception block,
						// we need to propagate the new state to the exception handler
						for (int j = 0; j < exceptions.Length; j++)
						{
							if (exceptions[j].endIndex == i + 1)
							{
								state[exceptions[j].handlerIndex].Merge(curr);
							}
						}
					}

					if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
					{
						ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instructions[i].Arg1);
						if (ReferenceEquals(cpi.Name, StringConstants.INIT))
						{
							TypeWrapper type = codeInfo.GetRawStackTypeWrapper(i, cpi.GetArgTypes().Length);
							// after we've invoked the constructor, the uninitialized references
							// are now initialized
							if (type == VerifierTypeWrapper.UninitializedThis
								|| VerifierTypeWrapper.IsNew(type))
							{
								for (int j = 0; j < maxLocals; j++)
								{
									if (codeInfo.GetLocalTypeWrapper(i, j) == type)
									{
										curr.Store(i, j);
									}
								}
							}
						}
					}
					else if (instructions[i].NormalizedOpCode == NormalizedByteCode.__goto_finally)
					{
						int handler = instructions[i].HandlerIndex;

						// Normally a store at the end of a try block doesn't affect the handler block,
						// but in the case of a finally handler it does, so we need to make sure that
						// we merge here in case the try block ended with a store.
						state[handler].Merge(curr);

						// Now we recursively analyse the handler and afterwards merge the endfault locations back to us
						FindLocalVarState[] handlerState = new FindLocalVarState[instructions.Length];
						handlerState[handler].Merge(curr);
						curr = new FindLocalVarState();
						FindLocalVariablesImpl(codeInfo, classFile, method, handlerState);

						// Merge back to the target of our __goto_finally
						for (int j = 0; j < handlerState.Length; j++)
						{
							if (instructions[j].NormalizedOpCode == NormalizedByteCode.__athrow
								&& codeInfo.HasState(j)
								&& VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0))
								&& ((VerifierTypeWrapper)codeInfo.GetRawStackTypeWrapper(j, 0)).Index == handler)
							{
								curr.Merge(handlerState[j]);
							}
						}
					}

					switch (ByteCodeMetaData.GetFlowControl(instructions[i].NormalizedOpCode))
					{
						case ByteCodeFlowControl.Switch:
							{
								for (int j = 0; j < instructions[i].SwitchEntryCount; j++)
								{
									state[instructions[i].GetSwitchTargetIndex(j)].Merge(curr);
								}
								state[instructions[i].DefaultTarget].Merge(curr);
								break;
							}
						case ByteCodeFlowControl.Branch:
							state[instructions[i].TargetIndex].Merge(curr);
							break;
						case ByteCodeFlowControl.CondBranch:
							state[instructions[i].TargetIndex].Merge(curr);
							state[i + 1].Merge(curr);
							break;
						case ByteCodeFlowControl.Return:
						case ByteCodeFlowControl.Throw:
							break;
						case ByteCodeFlowControl.Next:
							state[i + 1].Merge(curr);
							break;
						default:
							throw new InvalidOperationException();
					}
				}
			}
		}
		return localStoreReaders;
	}
Пример #42
0
 /// <summary>
 /// Try to load a class from import mappings.
 /// </summary>
 bool IClassLoader.TryLoadClass(string className, out ClassFile result)
 {
     return(assemblyClassLoader.TryLoadClass(className, out result));
 }
Пример #43
0
	internal LocalVarInfo(CodeInfo ma, ClassFile classFile, ClassFile.Method method, UntangledExceptionTable exceptions, MethodWrapper mw, ClassLoaderWrapper classLoader)
	{
		Dictionary<int, string>[] localStoreReaders = FindLocalVariables(ma, mw, classFile, method);

		// now that we've done the code flow analysis, we can do a liveness analysis on the local variables
		ClassFile.Method.Instruction[] instructions = method.Instructions;
		Dictionary<long, LocalVar> localByStoreSite = new Dictionary<long, LocalVar>();
		List<LocalVar> locals = new List<LocalVar>();
		for (int i = 0; i < localStoreReaders.Length; i++)
		{
			if (localStoreReaders[i] != null)
			{
				VisitLocalLoads(ma, method, locals, localByStoreSite, localStoreReaders[i], i, classLoader.EmitDebugInfo);
			}
		}
		Dictionary<LocalVar, LocalVar> forwarders = new Dictionary<LocalVar, LocalVar>();
		if (classLoader.EmitDebugInfo)
		{
			InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(ma, method.Instructions, exceptions, 0, false);
			// if we're emitting debug info, we need to keep dead stores as well...
			for (int i = 0; i < instructions.Length; i++)
			{
				if ((flags[i] & InstructionFlags.Reachable) != 0
					&& IsStoreLocal(instructions[i].NormalizedOpCode))
				{
					if (!localByStoreSite.ContainsKey(MakeKey(i, instructions[i].NormalizedArg1)))
					{
						LocalVar v = new LocalVar();
						v.local = instructions[i].NormalizedArg1;
						v.type = ma.GetStackTypeWrapper(i, 0);
						FindLvtEntry(v, method, i);
						locals.Add(v);
						localByStoreSite.Add(MakeKey(i, v.local), v);
					}
				}
			}
			// to make the debugging experience better, we have to trust the
			// LocalVariableTable (unless it's clearly bogus) and merge locals
			// together that are the same according to the LVT
			for (int i = 0; i < locals.Count - 1; i++)
			{
				for (int j = i + 1; j < locals.Count; j++)
				{
					LocalVar v1 = (LocalVar)locals[i];
					LocalVar v2 = (LocalVar)locals[j];
					if (v1.name != null && v1.name == v2.name && v1.start_pc == v2.start_pc && v1.end_pc == v2.end_pc)
					{
						// we can only merge if the resulting type is valid (this protects against incorrect
						// LVT data, but is also needed for constructors, where the uninitialized this is a different
						// type from the initialized this)
						TypeWrapper tw = InstructionState.FindCommonBaseType(v1.type, v2.type);
						if (tw != VerifierTypeWrapper.Invalid)
						{
							v1.isArg |= v2.isArg;
							v1.type = tw;
							forwarders.Add(v2, v1);
							locals.RemoveAt(j);
							j--;
						}
					}
				}
			}
		}
		else
		{
			for (int i = 0; i < locals.Count - 1; i++)
			{
				for (int j = i + 1; j < locals.Count; j++)
				{
					LocalVar v1 = (LocalVar)locals[i];
					LocalVar v2 = (LocalVar)locals[j];
					// if the two locals are the same, we merge them, this is a small
					// optimization, it should *not* be required for correctness.
					if (v1.local == v2.local && v1.type == v2.type)
					{
						v1.isArg |= v2.isArg;
						forwarders.Add(v2, v1);
						locals.RemoveAt(j);
						j--;
					}
				}
			}
		}
		invokespecialLocalVars = new LocalVar[instructions.Length][];
		localVars = new LocalVar[instructions.Length];
		for (int i = 0; i < localVars.Length; i++)
		{
			LocalVar v = null;
			if (localStoreReaders[i] != null)
			{
				Debug.Assert(IsLoadLocal(instructions[i].NormalizedOpCode));
				// lame way to look up the local variable for a load
				// (by indirecting through a corresponding store)
				foreach (int store in localStoreReaders[i].Keys)
				{
					v = localByStoreSite[MakeKey(store, instructions[i].NormalizedArg1)];
					break;
				}
			}
			else
			{
				if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
				{
					invokespecialLocalVars[i] = new LocalVar[method.MaxLocals];
					for (int j = 0; j < invokespecialLocalVars[i].Length; j++)
					{
						localByStoreSite.TryGetValue(MakeKey(i, j), out invokespecialLocalVars[i][j]);
					}
				}
				else
				{
					localByStoreSite.TryGetValue(MakeKey(i, instructions[i].NormalizedArg1), out v);
				}
			}
			if (v != null)
			{
				LocalVar fwd;
				if (forwarders.TryGetValue(v, out fwd))
				{
					v = fwd;
				}
				localVars[i] = v;
			}
		}
		this.allLocalVars = locals.ToArray();
	}
Пример #44
0
        public void Test()
        {
            var cf = new ClassFile(new MemoryStream(Resources.HalloAndroidActivity), null);

            Assert.AreEqual("org/hello/HalloAndroidActivity", cf.ClassName);
        }
Пример #45
0
			internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
				name = classFile.GetConstantPoolUtf8String(utf8_cp, name_index);
				if(name.Length > 0)
				{
					// We don't enforce the strict class name rules in the static compiler, since HotSpot doesn't enforce *any* rules on
					// class names for the system (and boot) class loader. We still need to enforce the 1.5 restrictions, because we
					// rely on those invariants.
#if !STATIC_COMPILER
					if(classFile.MajorVersion < 49 && (options & ClassFileParseOptions.RelaxedClassNameValidation) == 0)
					{
						char prev = name[0];
						if(Char.IsLetter(prev) || prev == '$' || prev == '_' || prev == '[' || prev == '/')
						{
							int skip = 1;
							int end = name.Length;
							if(prev == '[')
							{
								if(!IsValidFieldSig(name))
								{
									goto barf;
								}
								while(name[skip] == '[')
								{
									skip++;
								}
								if(name.EndsWith(";"))
								{
									end--;
								}
							}
							for(int i = skip; i < end; i++)
							{
								char c = name[i];
								if(!Char.IsLetterOrDigit(c) && c != '$' && c != '_' && (c != '/' || prev == '/'))
								{
									goto barf;
								}
								prev = c;
							}
							name = String.Intern(name.Replace('/', '.'));
							return;
						}
					}
					else
#endif
					{
						// since 1.5 the restrictions on class names have been greatly reduced
						int end = name.Length;
						if(name[0] == '[')
						{
							if(!IsValidFieldSig(name))
							{
								goto barf;
							}
							// the semicolon is only allowed at the end and IsValidFieldSig enforces this,
							// but since invalidJava15Characters contains the semicolon, we decrement end
							// to make the following check against invalidJava15Characters ignore the
							// trailing semicolon.
							if(name[end - 1] == ';')
							{
								end--;
							}
						}
						if(name.IndexOfAny(invalidJava15Characters, 0, end) >= 0)
						{
							goto barf;
						}
						name = String.Intern(name.Replace('/', '.'));
						return;
					}
				}
				barf:
					throw new ClassFormatError("Invalid class name \"{0}\"", name);
			}
Пример #46
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangMathBuilder(ClassFile cf)
     : base(cf, "System.Math", "java/lang/Math")
 {
 }
Пример #47
0
			internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
				switch ((RefKind)ref_kind)
				{
					case RefKind.getField:
					case RefKind.getStatic:
					case RefKind.putField:
					case RefKind.putStatic:
						cpi = classFile.GetConstantPoolItem(method_index) as ConstantPoolItemFieldref;
						break;
					case RefKind.invokeSpecial:
					case RefKind.invokeVirtual:
					case RefKind.invokeStatic:
					case RefKind.newInvokeSpecial:
						cpi = classFile.GetConstantPoolItem(method_index) as ConstantPoolItemMethodref;
						break;
					case RefKind.invokeInterface:
						cpi = classFile.GetConstantPoolItem(method_index) as ConstantPoolItemInterfaceMethodref;
						break;
				}
				if (cpi == null)
				{
					throw new ClassFormatError("Invalid constant pool item MethodHandle");
				}
				if (ReferenceEquals(cpi.Name, StringConstants.INIT) && Kind != RefKind.newInvokeSpecial)
				{
					throw new ClassFormatError("Bad method name");
				}
			}
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangArrayStoreExceptionBuilder(ClassFile cf)
     : base(cf, "System.ArrayTypeMismatchException", "java/lang/ArrayStoreException")
 {
 }
Пример #49
0
			internal override void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
			{
				ConstantPoolItemNameAndType name_and_type = (ConstantPoolItemNameAndType)classFile.GetConstantPoolItem(name_and_type_index);
				// if the constant pool items referred to were strings, GetConstantPoolItem returns null
				if (name_and_type == null)
				{
					throw new ClassFormatError("Bad index in constant pool");
				}
				name = String.Intern(classFile.GetConstantPoolUtf8String(utf8_cp, name_and_type.name_index));
				descriptor = String.Intern(classFile.GetConstantPoolUtf8String(utf8_cp, name_and_type.descriptor_index).Replace('/', '.'));
			}
        //void ShowUnknownGUI()
        //{
        //    EditorGUILayout.Space();
        //    showUnknownFoldout = GUILayoutHelper.Foldout(showUnknownFoldout, new GUIContent("Unknown"), () =>
        //    {
        //        EditorGUILayout.Space();
        //        GUILayoutHelper.Indent(() =>
        //        {
        //            EditorGUILayout.LabelField("Unknown1 [1 Bytes]");
        //            EditorGUILayout.SelectableLabel(selectedCareer.RawData.Unknown1.ToString("X2"), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        //        });
        //        GUILayoutHelper.Indent(() =>
        //        {
        //            EditorGUILayout.LabelField("Unknown2 [8 Bytes]");
        //            string valuesString = string.Empty;
        //            for (int i = 0; i < selectedCareer.RawData.Unknown2.Length; i++)
        //            {
        //                valuesString += selectedCareer.RawData.Unknown2[i].ToString("X2") + " ";
        //            }
        //            EditorGUILayout.SelectableLabel(valuesString, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        //        });
        //    });
        //}

        bool IsReady()
        {
            dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
            {
                return(false);
            }

            // Read all CLASS*.CFG files
            if (classTemplates == null)
            {
                string[] files = Directory.GetFiles(dfUnity.Arena2Path, "class*.cfg");
                if (files != null && files.Length > 0)
                {
                    classTemplates = new DFCareer[files.Length - 1];
                    classNames     = new GUIContent[files.Length - 1];
                    for (int i = 0; i < files.Length - 1; i++)
                    {
                        ClassFile classFile = new ClassFile(files[i]);
                        classTemplates[i] = classFile.Career;
                        classNames[i]     = new GUIContent(classTemplates[i].Name);
                    }
                }
            }

            // Read all ENEMY*.CFG files
            if (monsterTemplates == null)
            {
                MonsterFile monsterFile = new MonsterFile();
                if (monsterFile.Load(Path.Combine(dfUnity.Arena2Path, MonsterFile.Filename), FileUsage.UseMemory, true))
                {
                    // First pass locates CFG record indices
                    List <int> cfgIndices = new List <int>();
                    for (int i = 0; i < monsterFile.Count; i++)
                    {
                        string recordName = monsterFile.GetRecordName(i);
                        if (recordName.EndsWith(".cfg", StringComparison.InvariantCultureIgnoreCase))
                        {
                            cfgIndices.Add(i);
                        }
                    }

                    // Second pass populates arrays
                    monsterTemplates = new DFCareer[cfgIndices.Count];
                    monsterNames     = new GUIContent[cfgIndices.Count];
                    for (int i = 0; i < cfgIndices.Count; i++)
                    {
                        // Read ENEMY.CFG class file from stream
                        ClassFile    classFile = new ClassFile();
                        byte[]       data      = monsterFile.GetRecordBytes(cfgIndices[i]);
                        MemoryStream stream    = new MemoryStream(data);
                        BinaryReader reader    = new BinaryReader(stream);
                        classFile.Load(reader);
                        reader.Close();

                        // Add to arrays
                        monsterTemplates[i] = classFile.Career;
                        monsterNames[i]     = new GUIContent(monsterTemplates[i].Name);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #51
0
			internal FieldOrMethod(ClassFile classFile, string[] utf8_cp, BigEndianBinaryReader br)
			{
				access_flags = (Modifiers)br.ReadUInt16();
				name = String.Intern(classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16()));
				descriptor = classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16());
				ValidateSig(classFile, descriptor);
				descriptor = String.Intern(descriptor.Replace('/', '.'));
			}
 /// <summary>
 /// Default ctor
 /// </summary>
 internal AndroidAppActivityBuilder(ClassFile cf)
     : base(cf, "android/app/Activity")
 {
 }
Пример #53
0
			internal Field(ClassFile classFile, string[] utf8_cp, BigEndianBinaryReader br) : base(classFile, utf8_cp, br)
			{
				if((IsPrivate && IsPublic) || (IsPrivate && IsProtected) || (IsPublic && IsProtected)
					|| (IsFinal && IsVolatile)
					|| (classFile.IsInterface && (!IsPublic || !IsStatic || !IsFinal || IsTransient)))
				{
					throw new ClassFormatError("{0} (Illegal field modifiers: 0x{1:X})", classFile.Name, access_flags);
				}
				int attributes_count = br.ReadUInt16();
				for(int i = 0; i < attributes_count; i++)
				{
					switch(classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16()))
					{
						case "Deprecated":
							if(br.ReadUInt32() != 0)
							{
								throw new ClassFormatError("Invalid Deprecated attribute length");
							}
							flags |= FLAG_MASK_DEPRECATED;
							break;
						case "ConstantValue":
						{
							if(br.ReadUInt32() != 2)
							{
								throw new ClassFormatError("Invalid ConstantValue attribute length");
							}
							ushort index = br.ReadUInt16();
							try
							{
								switch(Signature)
								{
									case "I":
										constantValue = classFile.GetConstantPoolConstantInteger(index);
										break;
									case "S":
										constantValue = (short)classFile.GetConstantPoolConstantInteger(index);
										break;
									case "B":
										constantValue = (byte)classFile.GetConstantPoolConstantInteger(index);
										break;
									case "C":
										constantValue = (char)classFile.GetConstantPoolConstantInteger(index);
										break;
									case "Z":
										constantValue = classFile.GetConstantPoolConstantInteger(index) != 0;
										break;
									case "J":
										constantValue = classFile.GetConstantPoolConstantLong(index);
										break;
									case "F":
										constantValue = classFile.GetConstantPoolConstantFloat(index);
										break;
									case "D":
										constantValue = classFile.GetConstantPoolConstantDouble(index);
										break;
									case "Ljava.lang.String;":
										constantValue = classFile.GetConstantPoolConstantString(index);
										break;
									default:
										throw new ClassFormatError("{0} (Invalid signature for constant)", classFile.Name);
								}
							}
							catch(InvalidCastException)
							{
								throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
							}
							catch(IndexOutOfRangeException)
							{
								throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
							}
							catch(InvalidOperationException)
							{
								throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
							}
							catch(NullReferenceException)
							{
								throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
							}
							break;
						}
						case "Signature":
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							if(br.ReadUInt32() != 2)
							{
								throw new ClassFormatError("Signature attribute has incorrect length");
							}
							signature = classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16());
							break;
						case "RuntimeVisibleAnnotations":
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							annotations = ReadAnnotations(br, classFile, utf8_cp);
							break;
						case "RuntimeInvisibleAnnotations":
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							foreach(object[] annot in ReadAnnotations(br, classFile, utf8_cp))
							{
								if(annot[1].Equals("Likvm/lang/Property;"))
								{
									DecodePropertyAnnotation(classFile, annot);
								}
#if STATIC_COMPILER
								else if(annot[1].Equals("Likvm/lang/Internal;"))
								{
									this.access_flags &= ~Modifiers.AccessMask;
									flags |= FLAG_MASK_INTERNAL;
								}
#endif
							}
							break;
						default:
							br.Skip(br.ReadUInt32());
							break;
					}
				}
			}
Пример #54
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangByteBuilder(ClassFile cf)
     : base(cf, "System.SByte", "java/lang/Byte")
 {
 }
Пример #55
0
			internal Method(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options, BigEndianBinaryReader br) : base(classFile, utf8_cp, br)
			{
				// vmspec 4.6 says that all flags, except ACC_STRICT are ignored on <clinit>
				// however, since Java 7 it does need to be marked static
				if(ReferenceEquals(Name, StringConstants.CLINIT) && ReferenceEquals(Signature, StringConstants.SIG_VOID) && (classFile.MajorVersion < 51 || IsStatic))
				{
					access_flags &= Modifiers.Strictfp;
					access_flags |= (Modifiers.Static | Modifiers.Private);
				}
				else
				{
					// LAMESPEC: vmspec 4.6 says that abstract methods can not be strictfp (and this makes sense), but
					// javac (pre 1.5) is broken and marks abstract methods as strictfp (if you put the strictfp on the class)
					if((ReferenceEquals(Name, StringConstants.INIT) && (IsStatic || IsSynchronized || IsFinal || IsAbstract || IsNative))
						|| (IsPrivate && IsPublic) || (IsPrivate && IsProtected) || (IsPublic && IsProtected)
						|| (IsAbstract && (IsFinal || IsNative || IsPrivate || IsStatic || IsSynchronized))
						|| (classFile.IsInterface && (!IsPublic || !IsAbstract)))
					{
						throw new ClassFormatError("{0} (Illegal method modifiers: 0x{1:X})", classFile.Name, access_flags);
					}
				}
				int attributes_count = br.ReadUInt16();
				for(int i = 0; i < attributes_count; i++)
				{
					switch(classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16()))
					{
						case "Deprecated":
							if(br.ReadUInt32() != 0)
							{
								throw new ClassFormatError("Invalid Deprecated attribute length");
							}
							flags |= FLAG_MASK_DEPRECATED;
							break;
						case "Code":
						{
							if(!code.IsEmpty)
							{
								throw new ClassFormatError("{0} (Duplicate Code attribute)", classFile.Name);
							}
							BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
							code.Read(classFile, utf8_cp, this, rdr, options);
							if(!rdr.IsAtEnd)
							{
								throw new ClassFormatError("{0} (Code attribute has wrong length)", classFile.Name);
							}
							break;
						}
						case "Exceptions":
						{
							if(exceptions != null)
							{
								throw new ClassFormatError("{0} (Duplicate Exceptions attribute)", classFile.Name);
							}
							BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
							ushort count = rdr.ReadUInt16();
							exceptions = new string[count];
							for(int j = 0; j < count; j++)
							{
								exceptions[j] = classFile.GetConstantPoolClass(rdr.ReadUInt16());
							}
							if(!rdr.IsAtEnd)
							{
								throw new ClassFormatError("{0} (Exceptions attribute has wrong length)", classFile.Name);
							}
							break;
						}
						case "Signature":
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							if(br.ReadUInt32() != 2)
							{
								throw new ClassFormatError("Signature attribute has incorrect length");
							}
							signature = classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16());
							break;
						case "RuntimeVisibleAnnotations":
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							annotations = ReadAnnotations(br, classFile, utf8_cp);
							break;
						case "RuntimeVisibleParameterAnnotations":
						{
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							if(low == null)
							{
								low = new LowFreqData();
							}
							BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
							byte num_parameters = rdr.ReadByte();
							low.parameterAnnotations = new object[num_parameters][];
							for(int j = 0; j < num_parameters; j++)
							{
								ushort num_annotations = rdr.ReadUInt16();
								low.parameterAnnotations[j] = new object[num_annotations];
								for(int k = 0; k < num_annotations; k++)
								{
									low.parameterAnnotations[j][k] = ReadAnnotation(rdr, classFile, utf8_cp);
								}
							}
							if(!rdr.IsAtEnd)
							{
								throw new ClassFormatError("{0} (RuntimeVisibleParameterAnnotations attribute has wrong length)", classFile.Name);
							}
							break;
						}
						case "AnnotationDefault":
						{
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							if(low == null)
							{
								low = new LowFreqData();
							}
							BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
							low.annotationDefault = ReadAnnotationElementValue(rdr, classFile, utf8_cp);
							if(!rdr.IsAtEnd)
							{
								throw new ClassFormatError("{0} (AnnotationDefault attribute has wrong length)", classFile.Name);
							}
							break;
						}
#if STATIC_COMPILER
						case "RuntimeInvisibleAnnotations":
							if(classFile.MajorVersion < 49)
							{
								goto default;
							}
							foreach(object[] annot in ReadAnnotations(br, classFile, utf8_cp))
							{
								if(annot[1].Equals("Likvm/lang/Internal;"))
								{
									if (classFile.IsInterface)
									{
										StaticCompiler.IssueMessage(Message.InterfaceMethodCantBeInternal, classFile.Name, this.Name, this.Signature);
									}
									else
									{
										this.access_flags &= ~Modifiers.AccessMask;
										flags |= FLAG_MASK_INTERNAL;
									}
								}
								if(annot[1].Equals("Likvm/internal/HasCallerID;"))
								{
									flags |= FLAG_HAS_CALLERID;
								}
								if(annot[1].Equals("Likvm/lang/DllExport;"))
								{
									string name = null;
									int? ordinal = null;
									for (int j = 2; j < annot.Length; j += 2)
									{
										if (annot[j].Equals("name") && annot[j + 1] is string)
										{
											name = (string)annot[j + 1];
										}
										else if (annot[j].Equals("ordinal") && annot[j + 1] is int)
										{
											ordinal = (int)annot[j + 1];
										}
									}
									if (name != null && ordinal != null)
									{
										if (!IsStatic)
										{
											StaticCompiler.IssueMessage(Message.DllExportMustBeStaticMethod, classFile.Name, this.Name, this.Signature);
										}
										else
										{
											if (low == null)
											{
												low = new LowFreqData();
											}
											low.DllExportName = name;
											low.DllExportOrdinal = ordinal.Value;
										}
									}
								}
							}
							break;
#endif
						default:
							br.Skip(br.ReadUInt32());
							break;
					}
				}
				if(IsAbstract || IsNative)
				{
					if(!code.IsEmpty)
					{
						throw new ClassFormatError("Abstract or native method cannot have a Code attribute");
					}
				}
				else
				{
					if(code.IsEmpty)
					{
						if(ReferenceEquals(this.Name, StringConstants.CLINIT))
						{
							code.verifyError = string.Format("Class {0}, method {1} signature {2}: No Code attribute", classFile.Name, this.Name, this.Signature);
							return;
						}
						throw new ClassFormatError("Method has no Code attribute");
					}
				}
			}
Пример #56
0
 internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags)
 {
     if (i >= 3 &&
         (flags[i - 0] & InstructionFlags.BranchTarget) == 0 &&
         (flags[i - 1] & InstructionFlags.BranchTarget) == 0 &&
         (flags[i - 2] & InstructionFlags.BranchTarget) == 0 &&
         (flags[i - 3] & InstructionFlags.BranchTarget) == 0 &&
         code[i - 1].NormalizedOpCode == NormalizedByteCode.__ldc &&
         code[i - 2].NormalizedOpCode == NormalizedByteCode.__ldc &&
         code[i - 3].NormalizedOpCode == NormalizedByteCode.__ldc)
     {
         // we now have a structural match, now we need to make sure that the argument values are what we expect
         TypeWrapper tclass    = classFile.GetConstantPoolClassType(code[i - 3].Arg1);
         TypeWrapper vclass    = classFile.GetConstantPoolClassType(code[i - 2].Arg1);
         string      fieldName = classFile.GetConstantPoolConstantString(code[i - 1].Arg1);
         if (tclass == wrapper && !vclass.IsUnloadable && !vclass.IsPrimitive && !vclass.IsNonPrimitiveValueType)
         {
             FieldWrapper field = wrapper.GetFieldWrapper(fieldName, vclass.SigName);
             if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass)
             {
                 // everything matches up, now call the actual emitter
                 DoEmit(context, wrapper, ilgen, field);
                 return(true);
             }
         }
     }
     return(false);
 }
Пример #57
0
				internal void Read(ClassFile classFile, string[] utf8_cp, Method method, BigEndianBinaryReader br, ClassFileParseOptions options)
				{
					max_stack = br.ReadUInt16();
					max_locals = br.ReadUInt16();
					uint code_length = br.ReadUInt32();
					if(code_length > 65535)
					{
						throw new ClassFormatError("{0} (Invalid Code length {1})", classFile.Name, code_length);
					}
					Instruction[] instructions = new Instruction[code_length + 1];
					int basePosition = br.Position;
					int instructionIndex = 0;
					try
					{
						BigEndianBinaryReader rdr = br.Section(code_length);
						while(!rdr.IsAtEnd)
						{
							instructions[instructionIndex].Read((ushort)(rdr.Position - basePosition), rdr, classFile);
							hasJsr |= instructions[instructionIndex].NormalizedOpCode == NormalizedByteCode.__jsr;
							instructionIndex++;
						}
						// we add an additional nop instruction to make it easier for consumers of the code array
						instructions[instructionIndex++].SetTermNop((ushort)(rdr.Position - basePosition));
					}
					catch(ClassFormatError x)
					{
						// any class format errors in the code block are actually verify errors
						verifyError = x.Message;
					}
					this.instructions = new Instruction[instructionIndex];
					Array.Copy(instructions, 0, this.instructions, 0, instructionIndex);
					// build the pcIndexMap
					int[] pcIndexMap = new int[this.instructions[instructionIndex - 1].PC + 1];
					for(int i = 0; i < pcIndexMap.Length; i++)
					{
						pcIndexMap[i] = -1;
					}
					for(int i = 0; i < instructionIndex - 1; i++)
					{
						pcIndexMap[this.instructions[i].PC] = i;
					}
					// convert branch offsets to indexes
					for(int i = 0; i < instructionIndex - 1; i++)
					{
						switch(this.instructions[i].NormalizedOpCode)
						{
							case NormalizedByteCode.__ifeq:
							case NormalizedByteCode.__ifne:
							case NormalizedByteCode.__iflt:
							case NormalizedByteCode.__ifge:
							case NormalizedByteCode.__ifgt:
							case NormalizedByteCode.__ifle:
							case NormalizedByteCode.__if_icmpeq:
							case NormalizedByteCode.__if_icmpne:
							case NormalizedByteCode.__if_icmplt:
							case NormalizedByteCode.__if_icmpge:
							case NormalizedByteCode.__if_icmpgt:
							case NormalizedByteCode.__if_icmple:
							case NormalizedByteCode.__if_acmpeq:
							case NormalizedByteCode.__if_acmpne:
							case NormalizedByteCode.__ifnull:
							case NormalizedByteCode.__ifnonnull:
							case NormalizedByteCode.__goto:
							case NormalizedByteCode.__jsr:
								this.instructions[i].SetTargetIndex(pcIndexMap[this.instructions[i].Arg1 + this.instructions[i].PC]);
								break;
							case NormalizedByteCode.__tableswitch:
							case NormalizedByteCode.__lookupswitch:
								this.instructions[i].MapSwitchTargets(pcIndexMap);
								break;
						}
					}
					// read exception table
					ushort exception_table_length = br.ReadUInt16();
					exception_table = new ExceptionTableEntry[exception_table_length];
					for(int i = 0; i < exception_table_length; i++)
					{
						ushort start_pc = br.ReadUInt16();
						ushort end_pc = br.ReadUInt16();
						ushort handler_pc = br.ReadUInt16();
						ushort catch_type = br.ReadUInt16();
						if(start_pc >= end_pc
							|| end_pc > code_length
							|| handler_pc >= code_length
							|| (catch_type != 0 && !classFile.SafeIsConstantPoolClass(catch_type)))
						{
							throw new ClassFormatError("Illegal exception table: {0}.{1}{2}", classFile.Name, method.Name, method.Signature);
						}
						classFile.MarkLinkRequiredConstantPoolItem(catch_type);
						// if start_pc, end_pc or handler_pc is invalid (i.e. doesn't point to the start of an instruction),
						// the index will be -1 and this will be handled by the verifier
						int startIndex = pcIndexMap[start_pc];
						int endIndex;
						if (end_pc == code_length)
						{
							// it is legal for end_pc to point to just after the last instruction,
							// but since there isn't an entry in our pcIndexMap for that, we have
							// a special case for this
							endIndex = instructionIndex - 1;
						}
						else
						{
							endIndex = pcIndexMap[end_pc];
						}
						int handlerIndex = pcIndexMap[handler_pc];
						exception_table[i] = new ExceptionTableEntry(startIndex, endIndex, handlerIndex, catch_type, i);
					}
					ushort attributes_count = br.ReadUInt16();
					for(int i = 0; i < attributes_count; i++)
					{
						switch(classFile.GetConstantPoolUtf8String(utf8_cp, br.ReadUInt16()))
						{
							case "LineNumberTable":
								if((options & ClassFileParseOptions.LineNumberTable) != 0)
								{
									BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
									int count = rdr.ReadUInt16();
									lineNumberTable = new LineNumberTableEntry[count];
									for(int j = 0; j < count; j++)
									{
										lineNumberTable[j].start_pc = rdr.ReadUInt16();
										lineNumberTable[j].line_number = rdr.ReadUInt16();
										if(lineNumberTable[j].start_pc >= code_length)
										{
											throw new ClassFormatError("{0} (LineNumberTable has invalid pc)", classFile.Name);
										}
									}
									if(!rdr.IsAtEnd)
									{
										throw new ClassFormatError("{0} (LineNumberTable attribute has wrong length)", classFile.Name);
									}
								}
								else
								{
									br.Skip(br.ReadUInt32());
								}
								break;
							case "LocalVariableTable":
								if((options & ClassFileParseOptions.LocalVariableTable) != 0)
								{
									BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
									int count = rdr.ReadUInt16();
									localVariableTable = new LocalVariableTableEntry[count];
									for(int j = 0; j < count; j++)
									{
										localVariableTable[j].start_pc = rdr.ReadUInt16();
										localVariableTable[j].length = rdr.ReadUInt16();
										localVariableTable[j].name = classFile.GetConstantPoolUtf8String(utf8_cp, rdr.ReadUInt16());
										localVariableTable[j].descriptor = classFile.GetConstantPoolUtf8String(utf8_cp, rdr.ReadUInt16()).Replace('/', '.');
										localVariableTable[j].index = rdr.ReadUInt16();
									}
									// NOTE we're intentionally not checking that we're at the end of the section
									// (optional attributes shouldn't cause ClassFormatError)
								}
								else
								{
									br.Skip(br.ReadUInt32());
								}
								break;
							default:
								br.Skip(br.ReadUInt32());
								break;
						}
					}
					// build the argmap
					string sig = method.Signature;
					List<int> args = new List<int>();
					int pos = 0;
					if(!method.IsStatic)
					{
						args.Add(pos++);
					}
					for(int i = 1; sig[i] != ')'; i++)
					{
						args.Add(pos++);
						switch(sig[i])
						{
							case 'L':
								i = sig.IndexOf(';', i);
								break;
							case 'D':
							case 'J':
								args.Add(-1);
								break;
							case '[':
							{
								while(sig[i] == '[')
								{
									i++;
								}
								if(sig[i] == 'L')
								{
									i = sig.IndexOf(';', i);
								}
								break;
							}
						}
					}
					argmap = args.ToArray();
					if(args.Count > max_locals)
					{
						throw new ClassFormatError("{0} (Arguments can't fit into locals)", classFile.Name);
					}
				}
Пример #58
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal JavaLangThreadBuilder(ClassFile cf)
     : base(cf, "System.Threading.Thread", "java/lang/Thread")
 {
 }
Пример #59
0
        /// <summary>
        /// Gets all classes that the given classes extends or implements
        /// </summary>
        private IEnumerable<ClassFile> SelfBaseAndImplementedClasses(ClassFile original)
        {
            // Return self
            yield return original;

            // Base classes
            var currentClass = original;
            while (currentClass != null)
            {
                if (currentClass.TryGetSuperClass(out currentClass))
                {
                    yield return currentClass;
                }
                else
                {
                    break;
                }
            }

            // Implemented interfaces
            currentClass = original;
            while (currentClass != null)
            {
                if (currentClass.Interfaces != null)
                {
                    foreach (var intfRef in currentClass.Interfaces)
                    {
                        ClassFile intfClass;
                        if (Loader.TryLoadClass(intfRef.ClassName, out intfClass))
                        {
                            foreach (var x in SelfBaseAndImplementedClasses(intfClass))
                            {
                                yield return x;
                            }
                        }
                    }
                }
                if (currentClass.TryGetSuperClass(out currentClass))
                {
                    yield return currentClass;
                }
                else
                {
                    break;
                }
            }
        }
Пример #60
0
        internal sealed override TypeWrapper DefineClassImpl(Dictionary <string, TypeWrapper> types, TypeWrapper host, ClassFile f, ClassLoaderWrapper classLoader, ProtectionDomain protectionDomain)
        {
#if STATIC_COMPILER
            AotTypeWrapper type = new AotTypeWrapper(f, (CompilerClassLoader)classLoader);
            type.CreateStep1();
            types[f.Name] = type;
            return(type);
#elif FIRST_PASS
            return(null);
#else
            // this step can throw a retargettable exception, if the class is incorrect
            DynamicTypeWrapper type = new DynamicTypeWrapper(host, f, classLoader, protectionDomain);
            // This step actually creates the TypeBuilder. It is not allowed to throw any exceptions,
            // if an exception does occur, it is due to a programming error in the IKVM or CLR runtime
            // and will cause a CriticalFailure and exit the process.
            type.CreateStep1();
            type.CreateStep2();
            if (types == null)
            {
                // we're defining an anonymous class, so we don't need any locking
                TieClassAndWrapper(type, protectionDomain);
                return(type);
            }
            lock (types)
            {
                // in very extreme conditions another thread may have beaten us to it
                // and loaded (not defined) a class with the same name, in that case
                // we'll leak the the Reflection.Emit defined type. Also see the comment
                // in ClassLoaderWrapper.RegisterInitiatingLoader().
                TypeWrapper race;
                types.TryGetValue(f.Name, out race);
                if (race == null)
                {
                    types[f.Name] = type;
                    TieClassAndWrapper(type, protectionDomain);
                }
                else
                {
                    throw new LinkageError("duplicate class definition: " + f.Name);
                }
            }
            return(type);
#endif // STATIC_COMPILER
        }