internal CompiledLambda Compile(Parameter[] parameters, object expr) { #if DEBUG if (m_traceOutput != null) { Monitor.Enter(m_traceOutput); m_traceOutput.WriteLine("------ Begin snipped ---------"); m_traceOutput.WriteLine("Body: {0}", expr); if (parameters != null) { foreach (Parameter p in parameters) { m_traceOutput.Write("\t{0}:{1}", p.ID, p.Type); if (p.VariableParam) m_traceOutput.Write("[&REST]"); m_traceOutput.WriteLine(); } } } try { #endif while (true) { bool proceed = false; expr = MacroExpand(expr, ref proceed); if (!proceed) break; } #if DEBUG if (m_traceOutput != null) m_traceOutput.WriteLine("Expanded: {0}", expr); #endif Stack<Type> st = new Stack<Type>(); if (parameters == null) parameters = new Parameter[0]; CompiledLambda lambda = new CompiledLambda(this, parameters); #if DEBUG ILGen il = lambda.CreateILGen(m_traceOutput); #else ILGen il = lambda.CreateILGen(); #endif LocalAccess localAccess = new LocalAccess(il, parameters); foreach (Parameter p in parameters) localAccess.BindParameter(p.ID, p.Type); CreateVariables(il, localAccess, expr); WriteEpilog(il, parameters, localAccess); CompileExpr(il, localAccess, st, expr); lambda.Values = localAccess.GetValues(); lambda.Consts = localAccess.GetConsts(); lambda.Dependences = localAccess.GetDependences(); Type retType = st.Pop(); if (ValueProxy.IsProxyType(retType)) { il.EmitPropertyGet(typeof(ValueProxy), "Value"); retType = typeof(System.Object); } else if (retType.IsValueType) il.EmitBoxing(retType); il.Emit(OpCodes.Ret); lambda.ReturnType = retType; if (lambda.Consts != null) { foreach (object obj in lambda.Consts) { // Notify object about compile IBindableObject cs = obj as IBindableObject; if (cs != null) cs.Bind(parameters, m_defaultPool); } } return lambda; #if DEBUG } finally { if (m_traceOutput != null) { m_traceOutput.WriteLine(); Monitor.Exit(m_traceOutput); } } #endif }
private void GetValueDependences(HashSet<Object> hs, Parameter[] parameters, CompiledLambda compiledExpr, List<SymbolLink> res, bool reviewLambdaExpr) { foreach (SymbolLink value in compiledExpr.Values) res.Add(value); if (compiledExpr.Consts != null) { foreach (object cn in compiledExpr.Consts) { IBindableObject bo = cn as IBindableObject; if (bo != null) bo.GetValueDependences(hs, parameters, reviewLambdaExpr, (SymbolLink value) => res.Add(value)); //foreach (FunctionLink dynFunc in bo.EnumDynamicFuncs()) // GetValueDependences(hs, dynFunc.Value, res, reviewLambdaExpr); } } foreach (LambdaExpr expr in compiledExpr.Dependences) if (reviewLambdaExpr || !expr.Isolate) { if (hs != null) { if (hs.Contains(expr)) continue; hs.Add(expr); } if (expr._compiledBody.Value == null) Compile(expr); GetValueDependences(hs, expr._parameters, expr._compiledBody.Value, res, reviewLambdaExpr); } }