Example #1
0
        private async Task <RoslynSimanticsModule> LoadModule(GameIffResource res)
        {
            var module = Parent.GetModuleFor(res);
            await module.GetModuleAsync();

            return(module);
        }
        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);
        }