internal TypeWrapper DefineClass(ClassFile f, object protectionDomain)
        {
#if NOEMIT
            throw new InvalidOperationException();
#else
            string dotnetAssembly = f.IKVMAssemblyAttribute;
            if (dotnetAssembly != null)
            {
                // It's a stub class generated by ikvmstub (or generated by the runtime when getResource was
                // called on a statically compiled class).
                ClassLoaderWrapper loader;
                try
                {
                    loader = ClassLoaderWrapper.GetAssemblyClassLoaderByName(dotnetAssembly);
                }
                catch (Exception x)
                {
                    // TODO don't catch all exceptions here
                    throw new NoClassDefFoundError(f.Name + " (" + x.Message + ")");
                }
                TypeWrapper tw = loader.LoadClassByDottedNameFast(f.Name);
                if (tw == null)
                {
                    throw new NoClassDefFoundError(f.Name + " (type not found in " + dotnetAssembly + ")");
                }
                return(RegisterInitiatingLoader(tw));
            }
            CheckDefineClassAllowed(f.Name);
            lock (types)
            {
                if (types.ContainsKey(f.Name))
                {
                    throw new LinkageError("duplicate class definition: " + f.Name);
                }
                // mark the type as "loading in progress", so that we can detect circular dependencies.
                types.Add(f.Name, null);
                defineClassInProgress.Add(f.Name, Thread.CurrentThread);
            }
            try
            {
                return(GetTypeWrapperFactory().DefineClassImpl(types, f, this, protectionDomain));
            }
            finally
            {
                lock (types)
                {
                    if (types[f.Name] == null)
                    {
                        // if loading the class fails, we remove the indicator that we're busy loading the class,
                        // because otherwise we get a ClassCircularityError if we try to load the class again.
                        types.Remove(f.Name);
                    }
                    defineClassInProgress.Remove(f.Name);
                    Monitor.PulseAll(types);
                }
            }
        }
Esempio n. 2
0
        internal static ClassLoaderWrapper GetGenericClassLoaderByName(string name)
        {
            Debug.Assert(name.StartsWith("[[") && name.EndsWith("]]"));
            Stack <List <ClassLoaderWrapper> > stack = new Stack <List <ClassLoaderWrapper> >();
            List <ClassLoaderWrapper>          list  = null;

            for (int i = 0; i < name.Length; i++)
            {
                if (name[i] == '[')
                {
                    if (name[i + 1] == '[')
                    {
                        stack.Push(list);
                        list = new List <ClassLoaderWrapper>();
                        if (name[i + 2] == '[')
                        {
                            i++;
                        }
                    }
                    else
                    {
                        int start = i + 1;
                        i = name.IndexOf(']', i);
                        list.Add(ClassLoaderWrapper.GetAssemblyClassLoaderByName(name.Substring(start, i - start)));
                    }
                }
                else if (name[i] == ']')
                {
                    ClassLoaderWrapper loader = GetGenericClassLoaderByKey(list.ToArray());
                    list = stack.Pop();
                    if (list == null)
                    {
                        return(loader);
                    }
                    list.Add(loader);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            throw new InvalidOperationException();
        }