public async Task <SimAnticsModule> CompileOrLoad()
        {
            var path = FilePath + ".dll";

            try
            {
                Module = FindModuleInAssembly(Assembly.LoadFrom(Path.GetFullPath(path)));
            }
            catch
            {
                // could not load module, try compile it.
                Module = await CompileModule();
            }
            if (Module == null)
            {
            }
            return(Module);
        }
        private VMRoutine RoutineFromModule(BHAV bhav, SimAnticsModule module)
        {
            object    func = module.GetFunction(bhav.ChunkID);
            VMRoutine routine;

            if (func != null)
            {
                if (func is IBHAV)
                {
                    routine = new VMAOTRoutine((IBHAV)func);
                }
                else
                {
                    routine = new VMAOTInlineRoutine((IInlineBHAV)func);
                }
            }
            else
            {
                routine = new VMRoutine();
            }
            PopulateRoutineFields(bhav, routine);
            return(routine);
        }
        public override VMRoutine Assemble(BHAV bhav, GameIffResource res)
        {
            VMRoutine routine;
            // firstly, try to find the assembly

            //var assembly = Assemblies.GetModuleFor(bhav.ChunkParent);

            // three possibilities:
            // - module is loading (null for now): create a JIT routine, which will be updated with the appropriate function when it is available
            // - module is finished loading: create an AOT routine, which hsa the function baked in
            // - forced interpreter (not impl yet)

            //if this bhav has a cached jit module, just use that rather than doing a lookup.

            var aot = (SimAnticsModule)bhav.ChunkParent.CachedJITModule;

            if (aot != null)
            {
                return(RoutineFromModule(bhav, aot));
            }

            var assembly = Assemblies.GetModuleFor(res);

            if (assembly != null)
            {
                if (assembly.Module != null)
                {
                    return(RoutineFromModule(bhav, assembly.Module));
                }
                // need to load it or wait for loading.
                var result = new VMRoslynRoutine();
                PopulateRoutineFields(bhav, result);
                assembly.GetModuleAsync().ContinueWith(moduleT =>
                {
                    //TODO: thread safe for server
                    // the main concern is injecting a JIT routine while the interpreter is running that function.
                    // in that case, it could attempt to enter into the the JIT routine at an invalid entry point
                    // (JIT execution can only enter from the start, loop points or after yield)
                    GameThread.InUpdate(() =>
                    {
                        SimAnticsModule module = (moduleT.IsFaulted) ? null : moduleT.Result;
                        object func            = module?.GetFunction(bhav.ChunkID);
                        if (func != null)
                        {
                            if (func is IBHAV)
                            {
                                result.SetJITRoutine((IBHAV)func);
                            }
                            else
                            {
                                result.SetJITRoutine((IInlineBHAV)func);
                            }
                        }
                        else
                        {
                            // failed... stay on interpreter
                        }
                    });
                });
                return(result);
            }

            routine = new VMRoutine();
            PopulateRoutineFields(bhav, routine);
            return(routine);
        }