private void EnsureCompiled(bool optimized) { //TODO too much duplicated code between these two blocks if (optimized) { if (_optimizedCode != null) return; var rewriter = new LightGlobalRewriter(); var newLambda = rewriter.RewriteLambda(Code, Code.Name, LanguageContext, optimized); _optimizedScope = rewriter.Scope; var compiler = new LightCompiler(); var interpreter = compiler.CompileTop(newLambda); _optimizedCode = new LightLambda(interpreter); } else { if (_code != null) return; var rewriter = new LightGlobalRewriter(); var newLambda = rewriter.RewriteLambda(Code, Code.Name, LanguageContext, optimized); var compiler = new LightCompiler(); var interpreter = compiler.CompileTop(newLambda); _code = new LightLambda(interpreter); } }
internal Delegate CreateDelegate(StrongBox<object>[] closure) { if (_compiled != null) { return CreateCompiledDelegate(closure); } // Otherwise, we'll create an interpreted LightLambda var ret = new LightLambda(_interpreter, closure, this); lock (this) { // If this field is now null, it means a compile happened if (_lightLambdas != null) { _lightLambdas.Add(ret); } } if (_lightLambdas == null) { return CreateCompiledDelegate(closure); } return ret.MakeDelegate(_lambda.Type); }
protected object InterpretLambdaInvoke(LightLambda targetLambda, object[] args) { if (ProducedStack > 0) { return targetLambda.Run(args); } else { return targetLambda.RunVoid(args); } }
/// <summary> /// If the target of invocation happens to be a delegate /// over enclosed instance lightLambda, return that instance. /// We can interpret LightLambdas directly. /// </summary> /// <param name="instance"></param> /// <param name="lightLambda"></param> /// <returns></returns> protected static bool TryGetLightLambdaTarget(object instance, out LightLambda lightLambda) { var del = instance as Delegate; if ((object)del != null) { var thunk = del.Target as Func<object[], object>; if ((object)thunk != null) { lightLambda = thunk.Target as LightLambda; if (lightLambda != null) { return true; } } } lightLambda = null; return false; }
private Delegate CreateCompiledDelegate(StrongBox<object>[] closure) { // It's already compiled, and the types match, just use the // delegate directly. Delegate d = _compiled(closure); // The types might not match, if the delegate type we want is // not a Func/Action. In that case, use LightLambda to create // a new delegate of the right type. This is not the most // efficient approach, but to do better we need the ability to // compile into a DynamicMethod that we created. if (d.GetType() != _lambda.Type) { var ret = new LightLambda(_interpreter, closure, this); ret.Compiled = d; d = ret.MakeDelegate(_lambda.Type); } return d; }