Ejemplo n.º 1
0
        public Value Generate(IAstNode ast, Action <CodeGeneratorException> codeGenerationErroHandler)
        {
            try
            {
                // Prototypes, including extern are ignored as AST generation
                // adds them to the RuntimeState so that already has the declarations
                if (!(ast is FunctionDefinition definition))
                {
                    return(null);
                }

                // Anonymous functions are called immediately then removed from the JIT
                // so no point in setting them up as a lazy compilation item.
                if (definition.IsAnonymous)
                {
                    InitializeModuleAndPassManager( );
                    var function = ( IrFunction )definition.Accept(this);

                    // eagerly compile modules for anonymous functions as calling the function is the guaranteed next step
                    ulong jitHandle  = JIT.AddEagerlyCompiledModule(Module);
                    var   nativeFunc = JIT.GetFunctionDelegate <KaleidoscopeJIT.CallbackHandler0>(definition.Name);
                    var   retVal     = Context.CreateConstant(nativeFunc( ));
                    JIT.RemoveModule(jitHandle);
                    return(retVal);
                }

                // Unknown if any future input will call the function so don't even generate IR
                // until it is needed. JIT triggers the callback to generate the IR module so the JIT
                // can then generate native code only when required.
                FunctionDefinition implDefinition = CloneAndRenameFunction(definition);

                // register the generator as a stub with the original source name
                JIT.AddLazyFunctionGenerator(definition.Name, () =>
                {
                    InitializeModuleAndPassManager( );
                    var function = ( IrFunction )implDefinition.Accept(this);
                    return(implDefinition.Name, function.ParentModule);
                });
                return(null);
            }