Beispiel #1
0
        public override object Call(object[] args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args cannot be null");
            }

            int nargs = args.Length;

            Callable c;

            if (cache.TryGetValue(-1, out c) ||
                cache.TryGetValue(nargs, out c))
            {
                return(c.Call(args));
            }

            if (!baked)
            {
                try
                {
                    if (methods.Length == 1)
                    {
                        // make c fast
                        MethodBase mb = methods[0];

                        bool needContext = false;

#warning Remove when Mono fixed: https:                         //bugzilla.novell.com/show_bug.cgi?id=655439
                        Type dt = (nargs > 8 || IsParams(mb)) ? // for mono
                                  typeof(CallTargetN) : CallTargets.GetTargetType(needContext, nargs, false);
                        Delegate d = Delegate.CreateDelegate(dt, mb as MethodInfo, false);
                        if (d == null)
                        {
                            d = Delegate.CreateDelegate(typeof(CallTargetN), needContext ? context : null, mb as MethodInfo, false);
                        }

                        if (d != null)
                        {
                            if (dt == typeof(CallTargetN))
                            {
                                cache[-1] = c = Closure.Create(d);
                            }
                            else
                            {
                                cache[nargs] = c = Closure.Create(d);
                            }
                        }
                    }
                    else
                    {
                        Type[] targs = Array.ConvertAll <object, Type>(args, delegate(object input)
                        {
                            if (input == null)
                            {
                                return(typeof(object));
                            }
                            else
                            {
                                return(input.GetType());
                            }
                        });

                        MethodCandidate mc = meth.MakeBindingTarget(CallType.None, targs);
                        if (mc != null)
                        {
                            MethodBase mb = mc.Target.Method;

                            bool needContext = NeedContext(mb);     // TODO: check if can remove

#warning Remove when Mono fixed: https:                             //bugzilla.novell.com/show_bug.cgi?id=655439
                            Type dt = (nargs > 8 || IsParams(mb)) ? // for mono
                                      typeof(CallTargetN) : CallTargets.GetTargetType(needContext, nargs, false);
                            Delegate d = Delegate.CreateDelegate(dt, mb as MethodInfo, false);
                            if (d == null)
                            {
                                d = Delegate.CreateDelegate(typeof(CallTargetN), needContext ? context : null, mb as MethodInfo, false);
                            }

                            if (d != null)
                            {
                                cache[nargs] = c = Closure.Create(d);
                            }
                        }
                    }
                }
                catch
                {
                    ;
                }

                if (c != null)
                {
                    return(c.Call(args));
                }
            }
            // fallback
            baked = true;

            try
            {
                // DO NOT WANT!!!!
                return(meth.CallReflected(context, CallType.None, args));
            }
            catch (ArgumentTypeException ex)
            {
                return(Closure.AssertionViolation(meth.ToString(), ex.Message, args));
            }
        }
Beispiel #2
0
        public static object CompileCore(object expr)
        {
            // fast path for really simple stuff
            if (expr is SymbolId)
            {
                CallTarget0 n = delegate
                {
                    return(SymbolValue(expr));
                };
                return(Closure.Create(n));
            }

            AssemblyGenAttributes aga = ScriptDomainManager.Options.AssemblyGenAttributes;

            ScriptDomainManager.Options.AssemblyGenAttributes &= ~AssemblyGenAttributes.EmitDebugInfo;
            ScriptDomainManager.Options.AssemblyGenAttributes &= ~AssemblyGenAttributes.GenerateDebugAssemblies;
            ScriptDomainManager.Options.AssemblyGenAttributes &= ~AssemblyGenAttributes.DisableOptimizations;

            if (ScriptDomainManager.Options.DebugMode)
            {
                ScriptDomainManager.Options.AssemblyGenAttributes |= AssemblyGenAttributes.EmitDebugInfo;
                ScriptDomainManager.Options.AssemblyGenAttributes |= AssemblyGenAttributes.GenerateDebugAssemblies;
                ScriptDomainManager.Options.AssemblyGenAttributes |= AssemblyGenAttributes.DisableOptimizations;
                ScriptDomainManager.Options.DebugCodeGeneration    = true;
            }
            else
            {
                ScriptDomainManager.Options.DebugCodeGeneration = false;
            }

            ScriptDomainManager.Options.AssemblyGenAttributes |= AssemblyGenAttributes.SaveAndReloadAssemblies;
            // if you ever want to inspect the emitted dll's comment the following out (or skip in the debugger), use with care
            ScriptDomainManager.Options.AssemblyGenAttributes &= ~AssemblyGenAttributes.SaveAndReloadAssemblies;

            var prevt  = IronScheme.Compiler.Generator.AllowTransientBinding;
            var prevag = Compiler.Generator.CurrentAssemblyGen;

            if ((ScriptDomainManager.Options.AssemblyGenAttributes & AssemblyGenAttributes.SaveAndReloadAssemblies) != 0)
            {
                IronScheme.Compiler.Generator.AllowTransientBinding = false;

                ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly =
                    Compiler.Generator.CurrentAssemblyGen = AssemblyGen.CreateModuleAssembly(null);
            }
            else
            {
                Compiler.Generator.CurrentAssemblyGen = ScriptDomainManager.Options.DebugMode ?
                                                        ScriptDomainManager.CurrentManager.Snippets.DebugAssembly :
                                                        ScriptDomainManager.CurrentManager.Snippets.Assembly;
            }

            int c = Interlocked.Increment(ref evalcounter);

#if DEBUG
            Stopwatch sw = Stopwatch.StartNew();
#endif
            //Console.WriteLine(new Cons(expr).PrettyPrint);
            try
            {
                CodeBlock cb = IronSchemeLanguageContext.CompileExpr(new Cons(expr));
                cb.ExplicitCodeContextExpression = null;

                ScriptCode sc = Context.LanguageContext.CompileSourceCode(cb); //wrap

#if DEBUG
                sw.Stop();

                Trace.WriteLine(sw.Elapsed.TotalMilliseconds, string.Format("compile - eval-core({0:D3})", c));
                sw = Stopwatch.StartNew();
#endif
                try
                {
                    sc.LibraryGlobals  = Compiler.SimpleGenerator.libraryglobals;
                    sc.LibraryGlobalsN = Compiler.SimpleGenerator.libraryglobalsN;
                    sc.LibraryGlobalsX = Compiler.SimpleGenerator.libraryglobalsX;

                    ScriptModule sm = ScriptDomainManager.CurrentManager.CreateModule(string.Format("eval-core({0:D3})", c), sc);
                    sc = sm.GetScripts()[0];

#if DEBUG
                    sw.Stop();

                    Trace.WriteLine(sw.Elapsed.TotalMilliseconds, string.Format("compile*- eval-core({0:D3})", c));
#endif
                    CallTarget0 compiled = delegate
                    {
#if DEBUG
                        try
                        {
                            sw = Stopwatch.StartNew();
#endif
                        return(sc.Run(Context.ModuleContext.Module));

#if DEBUG
                    }

                    finally
                    {
                        sw.Stop();
                        Trace.WriteLine(sw.Elapsed.TotalMilliseconds, string.Format("run     - eval-core({0:D3})", c));
                    }
#endif
                    };
                    return(Closure.Create(compiled));
                }
                catch (Variable.UnInitializedUsageException ex)
                {
                    CallTarget0 err = delegate
                    {
                        return(AssertionViolation(ex.Variable.Block.Name, ex.Message, UnGenSym(ex.Variable.Name)));
                    };

                    return(Closure.Create(err));
                }
                finally
                {
                    BoundExpression.Fixups.Clear();
                    BoundExpression.FixupTypes.Clear();
                    Compiler.Generator.CurrentAssemblyGen               = prevag;
                    ScriptDomainManager.Options.AssemblyGenAttributes   = aga;
                    IronScheme.Compiler.Generator.AllowTransientBinding = prevt;
                    sc.ClearCache();
                    Compiler.SimpleGenerator.ClearGlobals();
                    Compiler.ClrGenerator.compiletimetypes.Clear();
                }
            }
            catch (Continuation)
            {
                throw;
            }
            catch (Exception ex)
            {
                var who = ex.Data["Who"];
                return(SyntaxError(who ?? FALSE, ex.Message, FALSE, FALSE));
            }
        }