Beispiel #1
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     il.Emit(OpCodes.Ldarg_1);
     il.EmitInt(locals.DefineConstant(args[0]));
     il.Emit(OpCodes.Ldelem_Ref);
     st.Push(typeof(System.Object));
 }
Beispiel #2
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 2)
         throw new ArgumentException("Unproperly formated cast expression");
     engine.CompileExpr(il, locals, st, args[0]);
     Type type = args[1] as Type;
     if (type == null)
         throw new ArgumentException("Expecting type value");
     Type curr_type = st.Pop();
     if (curr_type.IsValueType)
     {
         if (type == typeof(System.Object))
             il.EmitBoxing(curr_type);
         else if (curr_type != type)
             throw new InvalidCastException();
     }
     else
     {
         il.Emit(OpCodes.Isinst, type);
         il.Emit(OpCodes.Dup);
         Label ok = il.DefineLabel();
         il.Emit(OpCodes.Brtrue_S, ok);
         il.EmitCall(_raiseInvalidCast);
         il.MarkLabel(ok);
         if (type.IsValueType)
             il.EmitUnbox(type);
     }
     st.Push(type);
 }
Beispiel #3
0
 public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes)
 {
     for (int k = 0; k < parameterTypes.Length; k++)
         il.Emit(OpCodes.Pop);
     il.EmitFieldGet(typeof(DBNull), "Value");
     return typeof(DBNull);
 }
Beispiel #4
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 1)
         throw new ArgumentException("Unproperly formated expression");
     for (int k = 0; k < st.Count; k++)
         il.Emit(OpCodes.Pop);
     engine.CompileExpr(il, locals, st, args[0]);
     st.Pop();
     il.Emit(OpCodes.Ret);
     st.Push(typeof(System.Object));
 }
Beispiel #5
0
 public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes)
 {
     Label l_true = il.DefineLabel();
     Label l_false = il.DefineLabel();
     il.Emit(OpCodes.Brfalse_S, l_true);
     il.EmitNull();
     il.Emit(OpCodes.Br_S, l_false);
     il.MarkLabel(l_true);
     il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
     il.MarkLabel(l_false);
     return typeof(System.Object);
 }
Beispiel #6
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     for (int k = 0; k < args.Length; k++)
     {
         engine.CompileExpr(il, locals, st, args[k]);
         if (k > 0)
         {
             st.Pop();
             il.Emit(OpCodes.Pop);
         }
     }
 }
Beispiel #7
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 1 || !Lisp.IsAtom(args[0]))
         throw new ArgumentException("Unproperly formated expression");
     SymbolLink link = engine.Get(args[0]);
     il.Emit(OpCodes.Ldarg_3);
     il.Emit(OpCodes.Ldarg_1);
     il.EmitInt(locals.DefineConstant(link));
     il.Emit(OpCodes.Ldelem_Ref);
     il.EmitCall(m_memoryPoolGetData);
     st.Push(typeof(System.Object));
 }
Beispiel #8
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     Type resType = null;
     List<Branch> branches = new List<Branch>();
     for (int k = 0; k < args.Length; k++)
     {
         Label next = il.DefineLabel();
         object cur = args[k];
         if (!Lisp.IsCons(cur))
             throw new ArgumentException("Unproperly formated expression");
         object[] pair = Lisp.ToArray(cur);
         if (pair.Length != 2)
             throw new ArgumentException("Unproperly formated expression");
         engine.CompileExpr(il, locals, st, pair[0]);
         if (st.Pop() != typeof(System.Object))
             throw new ArgumentException("Expecting boolean value");
         il.Emit(OpCodes.Brfalse, next);
         engine.CompileExpr(il, locals, st, pair[1]);
         Type type = st.Pop();
         Branch branch = GetBranch(branches, il, type);
         il.Emit(OpCodes.Stloc, branch.localVar);
         il.Emit(OpCodes.Br, branch.handler);
         il.MarkLabel(next);
         if (resType == null)
             resType = type;
         else
             if (resType != type)
                 resType = typeof(System.Object);
     }
     il.EmitCall(_raiseError);
     Label end = il.DefineLabel();
     for (int k = 0; k < branches.Count; k++)
     {
         Branch b = branches[k];
         il.MarkLabel(b.handler);
         il.Emit(OpCodes.Ldloc, b.localVar);
         il.FreeLocal(b.localVar);
         if (resType != b.type)
         {
             if (ValueProxy.IsProxyType(b.type))
                 il.EmitPropertyGet(typeof(ValueProxy), "Value");
             else if (b.type.IsValueType)
                 il.Emit(OpCodes.Box, b.type);
         }
         if (k < branches.Count -1)
             il.Emit(OpCodes.Br, end);                
     }
     il.MarkLabel(end);
     st.Push(resType);
 }
Beispiel #9
0
 public override void CreateVariables(Executive engine, object form, ILGen il, LocalAccess locals, object[] args)
 {
     if (args.Length == 0)
         throw new ArgumentException("Unproperly formated expression");
     locals.DeclareScope(form);
     locals.EnterScope(form, _activeScope);
     foreach (object arg in Lisp.getIterator(args[0]))
     {
         object[] pair = Lisp.ToArray(arg);
         if (pair.Length != 2 || !Lisp.IsAtom(pair[0]))
             throw new ArgumentException("Unproperly formated expression");
         locals.DeclareLocal(pair[0]);
         engine.CreateVariables(il, locals, pair[1]);
     }
     if (!_activeScope)
         locals.ActivateScope();
     for (int k = 1; k < args.Length; k++)
         engine.CreateVariables(il, locals, args[k]);
     locals.LeaveScope();
 }
Beispiel #10
0
 public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes)
 {
     LocalBuilder[] localVar = new LocalBuilder[Name.Arity];
     for (int k = Name.Arity -1; k >= 0; k--)
     {
         localVar[k] = il.DeclareLocal(Name.Signature[k]);
         il.Emit(OpCodes.Stloc, localVar[k]);
     }
     il.Emit(OpCodes.Ldarg_1);
     il.EmitInt(locals.DefineConstant(m_delegate));
     il.Emit(OpCodes.Ldelem_Ref);
     il.Emit(OpCodes.Isinst, m_delegate.GetType());
     for (int k = 0; k < Name.Arity; k++)
     {
         il.Emit(OpCodes.Ldloc, localVar[k]);
         il.FreeLocal(localVar[k]);
     }
     il.EmitCall(m_delegate.GetType(), "Invoke");
     return m_delegate.Method.GetReturnType();
 }
Beispiel #11
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 2)
         throw new ArgumentException("Unproperly formated expression");
     engine.CompileExpr(il, locals, st, args[0]);
     if (st.Pop() != typeof(System.Object))
         throw new ArgumentException("Expecting boolean value");
     Label l_false = il.DefineLabel();            
     il.Emit(OpCodes.Brfalse, l_false);
     engine.CompileExpr(il, locals, st, args[1]);
     if (st.Pop() != typeof(System.Object))
         throw new ArgumentException("Expecting boolean value");
     Label end = il.DefineLabel();
     il.Emit(OpCodes.Brfalse_S, l_false);
     il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
     il.Emit(OpCodes.Br_S, end);
     il.MarkLabel(l_false);
     il.EmitNull();
     il.MarkLabel(end);
     st.Push(typeof(System.Object));
 }
Beispiel #12
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     LambdaExpr lambda = new LambdaExpr(null, locals.Parameters,
         typeof(System.Object), Lisp.Arg1(form));
     lambda.Isolate = false;
     Type[] parameterTypes = new Type[locals.Parameters.Length];
     for (int k = 0; k < parameterTypes.Length; k++)
     {
         //LocalBuilder local = locals.GetLocal(locals.Parameters[k].ID);
         //parameterTypes[k] = local.LocalType;
         //il.Emit(OpCodes.Ldloc, local);         
         parameterTypes[k] = locals.Parameters[k].Type;
         il.Emit(OpCodes.Ldarg_2);
         il.EmitInt(k);
         il.Emit(OpCodes.Ldelem_Ref);
         il.Emit(OpCodes.Isinst, parameterTypes[k]);
         if (parameterTypes[k].IsValueType)
             il.EmitUnbox(parameterTypes[k]);
     }
     st.Push(lambda.Compile(engine, il, locals, parameterTypes));
 }
Beispiel #13
0
        public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes)
        {
            switch (_case)
            {
                case 0:
                    il.Emit(_opcode);
                    break;

                case 1:
                    il.Emit(_opcode, _type);
                    break;

                case 2:
                    il.EmitCall(_type, _methodName);
                    break;

                case 3:
                    il.EmitCall(_type, _methodName, _paramTypes);
                    break;
            }
            
            return _returnType;
        }
Beispiel #14
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     locals.EnterScope(form, _activeScope);
     foreach (object arg in Lisp.getIterator(args[0]))
     {
         object[] pair = Lisp.ToArray(arg);
         engine.CompileExpr(il, locals, st, pair[1]);
         LocalBuilder localvar = locals.BindLocal(pair[0], st.Pop());
         il.Emit(OpCodes.Stloc, localvar);
     }
     if (!_activeScope)
         locals.ActivateScope();
     for (int k = 1; k < args.Length; k++)
     {
         engine.CompileExpr(il, locals, st, args[k]);
         if (k < args.Length - 1)
         {
             st.Pop();
             il.Emit(OpCodes.Pop);
         }
     }
     locals.DestroyScope();
 }
Beispiel #15
0
 private void WriteEpilog(ILGen il, Parameter[] parameters, LocalAccess locals)
 {
     if (locals.HasLocals || parameters.Length > 0)
     {
         Label label = il.DefineLabel();
         if (parameters.Length > 0)
         {
             for (int k = 0; k < parameters.Length; k++)
             {
                 il.Emit(OpCodes.Ldarg_2);
                 il.EmitInt(k);
                 il.Emit(OpCodes.Ldelem_Ref);
                 if (parameters[k].Type.IsValueType)
                 {
                     il.Emit(OpCodes.Isinst, parameters[k].Type);
                     il.Emit(OpCodes.Dup);
                     il.Emit(OpCodes.Brfalse, label);
                     if (locals.IsParameterBinded(parameters[k].ID))
                     {
                         LocalBuilder local = locals.GetLocal(parameters[k].ID);
                         il.EmitUnbox(local.LocalType);
                         il.Emit(OpCodes.Stloc, local);
                     }
                     else
                         il.Emit(OpCodes.Pop);
                 }
                 else
                 {
                     Label label2 = il.DefineLabel();
                     il.Emit(OpCodes.Dup);
                     il.Emit(OpCodes.Brfalse_S, label2);
                     il.Emit(OpCodes.Isinst, parameters[k].Type);
                     il.Emit(OpCodes.Dup);
                     il.Emit(OpCodes.Brfalse, label);
                     il.MarkLabel(label2);
                     if (locals.IsParameterBinded(parameters[k].ID))
                     {                                                                
                         LocalBuilder local = locals.GetLocal(parameters[k].ID);
                         il.Emit(OpCodes.Stloc, local);
                     }
                     else
                         il.Emit(OpCodes.Pop);
                 }
             }
         }
         if (locals.HasLocals)
         {
             il.Emit(OpCodes.Ldarg_0);
             il.EmitPropertyGet(typeof(CompiledLambda), "Values");
             LocalBuilder values = il.DeclareLocal(typeof(SymbolLink[]));
             il.Emit(OpCodes.Stloc, values);
             int k = 0;
             foreach (LocalAccess.LocalBinding b in locals)
             {
                 il.Emit(OpCodes.Ldarg_3);                        
                 il.Emit(OpCodes.Ldloc, values);
                 il.EmitInt(k++);
                 il.Emit(OpCodes.Ldelem_Ref);
                 il.EmitCall(m_memoryPoolGetData);
                 if (b.Local.LocalType.IsValueType)
                 {
                     il.Emit(OpCodes.Isinst, b.Local.LocalType);
                     il.Emit(OpCodes.Dup);
                     il.Emit(OpCodes.Brfalse, label);
                     il.EmitUnbox(b.Local.LocalType);
                     il.Emit(OpCodes.Stloc, b.Local);
                 }
                 else
                 {
                     Label label2 = il.DefineLabel();
                     il.Emit(OpCodes.Dup);
                     il.Emit(OpCodes.Brfalse_S, label2);
                     il.Emit(OpCodes.Isinst, b.Local.LocalType);
                     il.Emit(OpCodes.Dup);
                     il.Emit(OpCodes.Brfalse, label);
                     il.MarkLabel(label2);
                     il.Emit(OpCodes.Stloc, b.Local);
                 }
             }
             il.FreeLocal(values);
         }
         Label end = il.DefineLabel();
         il.Emit(OpCodes.Br_S, end);
         il.MarkLabel(label);
         il.Emit(OpCodes.Pop); // Isinst
         il.EmitPropertyGet(typeof(Undefined), "Value");
         il.Emit(OpCodes.Ret);
         il.MarkLabel(end);                
     }
 }
Beispiel #16
0
 internal void CompileExpr(ILGen il, LocalAccess locals, Stack<Type> st, object lval)
 {
     if (lval == null)
     {
         il.EmitNull();
         st.Push(typeof(System.Object));
     }
     else if (Lisp.IsNode(lval))
     {
         if (lval == Lisp.NIL || lval == Lisp.T)
         {
             if (lval == Lisp.NIL)
                 il.EmitNull();
             else
                 il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
             st.Push(typeof(System.Object));
         }
         else if (lval == Lisp.INST)
         {
             il.Emit(OpCodes.Ldarg_0);
             il.EmitPropertyGet(typeof(CompiledLambda), "Engine");
             st.Push(typeof(Executive));
         }
         else if (lval == Lisp.ARGV)
         {
             il.Emit(OpCodes.Ldarg_2);
             st.Push(typeof(object[]));
         }
         else if (lval == Lisp.MPOOL)
         {
             il.Emit(OpCodes.Ldarg_3);
             st.Push(typeof(MemoryPool));
         }
         else
         {
             LocalBuilder localVar = locals.GetLocal(lval);
             if (localVar != null)
             {
                 il.Emit(OpCodes.Ldloc, localVar);
                 st.Push(localVar.LocalType);
             }
             else
             {
                 Type type = lval.GetType();
                 if (type == typeof(Integer))
                 {
                     il.EmitDecimal((Decimal)((Integer)lval));
                     il.EmitNew(typeof(Integer).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null,
                         new Type[] { typeof(Decimal) }, null));
                 }
                 else if (!il.TryEmitConstant(lval, type))
                 {
                     il.Emit(OpCodes.Ldarg_1);
                     il.EmitInt(locals.DefineConstant(lval));
                     il.Emit(OpCodes.Ldelem_Ref);
                     if (type.IsValueType)
                         il.EmitUnbox(type);
                 }
                 st.Push(type);
             }
         }
     }
     else if (Lisp.IsFunctor(lval))
     {
         object head = Lisp.Car(lval);
         object[] args = Lisp.ToArray(Lisp.Cdr(lval));
         ControlFormBase control;
         if (m_control.TryGetValue(head, out control))
             control.Compile(this, lval, il, locals, st, args);
         else
         {
             foreach (object a in args)
                 CompileExpr(il, locals, st, a);
             Type[] parameterTypes = new Type[args.Length];
             for (int k = args.Length - 1; k >= 0; k--)
                 parameterTypes[k] = st.Pop();
             FuncName name = new FuncName(head, parameterTypes);
             FuncBase body = GetFunc(name, false);
             if (body == null)
             {
                 bool successed = false;
                 if (parameterTypes.Length == 2)
                 {
                     Type castType = ValueProxy.GetType(parameterTypes[0], parameterTypes[1]);
                     ValueConverter converter1 = FindConverter(parameterTypes[0], castType);
                     ValueConverter converter2 = FindConverter(parameterTypes[1], castType);
                     body = GetFunc(new FuncName(name.ID, new Type[] { castType, castType }), false);
                     if (body != null && converter1 != null && converter2 != null)
                     {
                         LocalBuilder localVar = il.DeclareLocal(parameterTypes[1]);
                         il.Emit(OpCodes.Stloc, localVar);
                         converter1.Compile(this, il, locals, parameterTypes[0]);
                         il.Emit(OpCodes.Ldloc, localVar);
                         il.FreeLocal(localVar);
                         converter2.Compile(this, il, locals, parameterTypes[1]);
                         successed = true;
                     }
                 }
                 if (!successed)
                 {
                     body = GetFunc(name, true);
                     if (body == null)
                         throw new UnknownFuncCall(name.ToString());
                     else
                     {
                         LocalBuilder[] localVar = new LocalBuilder[parameterTypes.Length];
                         for (int k = localVar.Length - 1; k >= 0; k--)
                         {
                             localVar[k] = il.DeclareLocal(parameterTypes[k]);
                             il.Emit(OpCodes.Stloc, localVar[k]);
                         }
                         Type[] new_parameter_types = new Type[parameterTypes.Length];
                         for (int k = 0; k < localVar.Length; k++)
                         {
                             il.Emit(OpCodes.Ldloc, localVar[k]);
                             if (body.Name.GetParameterType(k) != parameterTypes[k])                                         
                             {
                                 if (parameterTypes[k].IsValueType)
                                     il.EmitBoxing(parameterTypes[k]);
                                 else if (ValueProxy.IsProxyType(parameterTypes[k]))
                                     il.EmitPropertyGet(typeof(ValueProxy), "Value");
                                 new_parameter_types[k] = typeof(System.Object);
                             }
                             else
                                 new_parameter_types[k] = parameterTypes[k];
                             il.FreeLocal(localVar[k]);
                         }
                         parameterTypes = new_parameter_types;
                     }
                 }
             }
             Type resType = body.Compile(this, il, locals, parameterTypes);
             if (resType == typeof(System.Boolean))
             { // Implict boolean convertion
                 Label l_false = il.DefineLabel();
                 Label end = il.DefineLabel();
                 il.Emit(OpCodes.Brfalse_S, l_false);
                 il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
                 il.Emit(OpCodes.Br_S, end);
                 il.MarkLabel(l_false);
                 il.EmitNull();
                 il.MarkLabel(end);
                 st.Push(typeof(System.Object));
             }
             else if (resType == typeof(void))
             { // assume that all procedures returns t
                 il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
                 st.Push(typeof(System.Object));
             }
             else
                 st.Push(resType);
         }
     }
     else
         if (Lisp.IsFunctor(Lisp.Car(lval), Lisp.LAMBDA))
         {
             object form = Lisp.Car(lval);
             object body = Lisp.Car(Lisp.Cddr(form));
             object tail = Lisp.Cdr(lval);
             LambdaExpr lambda = new LambdaExpr(null, CreateParameters(Lisp.Arg1(form)),
                 typeof(System.Object), body);
             List<Type> parameterTypesList = new List<Type>();
             foreach (object a in Lisp.getIterator(tail))
             {
                 CompileExpr(il, locals, st, a);
                 parameterTypesList.Add(st.Pop());
             }
             Type[] parameterTypes = parameterTypesList.ToArray();
             FuncName name = new FuncName(null, parameterTypes);
             if (!lambda.Name.Match(name, true))
                 throw new InvalidOperationException("Lambda parameters does not match");
             st.Push(lambda.Compile(this, il, locals, parameterTypes));
         }
         else
             throw new ArgumentException("Unproperly formated expression");
 }
Beispiel #17
0
        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            
        }
Beispiel #18
0
 internal void CreateVariables(ILGen il, LocalAccess locals, object lval)
 {
     if (Lisp.IsNode(lval))
     {
         if (Lisp.IsAtom(lval) && lval != Lisp.NIL && lval != Lisp.T && lval != Lisp.INST && lval != Lisp.ARGV && lval != Lisp.MPOOL)
             locals.Bind(this, lval);
     }
     else if (Lisp.IsFunctor(lval))
     {
         object head = Lisp.Car(lval);
         object[] args = Lisp.ToArray(Lisp.Cdr(lval));
         ControlFormBase control;
         if (m_control.TryGetValue(head, out control))
             control.CreateVariables(this, lval, il, locals, args);
         else
         {
             foreach (object arg in args)
                 CreateVariables(il, locals, arg);
         }
     }
     else
     {
         object[] args = Lisp.ToArray(lval);
         if (Lisp.IsFunctor(Lisp.Car(lval), Lisp.LAMBDA))
         {
             for (int k = 1; k < args.Length; k++)
                 CreateVariables(il, locals, args[k]);
         }
         else
             foreach (object arg in args)
                 CreateVariables(il, locals, arg);
     }
 }
Beispiel #19
0
 public override void Compile(Executive engine, ILGen il, LocalAccess locals, Type sourceType)
 {
     il.EmitCall(_methodInfo[sourceType]);
 }
Beispiel #20
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length < 2)
         throw new ArgumentException();
     engine.CompileExpr(il, locals, st, args[0]);
     Type inst = st.Pop();
     il.Emit(OpCodes.Castclass, inst);
     String name = args[1].ToString();
     MethodInfo methodInfo;
     if (args.Length > 2)
     {
         Type[] parameters = new Type[args.Length - 2];
         ParameterModifier modifier = new ParameterModifier(parameters.Length);
         LocalBuilder[] localVar = new LocalBuilder[parameters.Length];
         for (int k = 0; k < args.Length - 2; k++)
         {
             engine.CompileExpr(il, locals, st, args[k + 2]);
             parameters[k] = st.Pop();
             localVar[k] = il.DeclareLocal(parameters[k]);
             il.Emit(OpCodes.Stloc, localVar[k]);
         }
         methodInfo = inst.GetMethod(name, parameters, new ParameterModifier[] { modifier });
         if (methodInfo == null)
             throw new ArgumentException("Method not found in class", name);
         ParameterInfo[] pi = methodInfo.GetParameters();
         for (int k = 0; k < pi.Length; k++)
         {
             il.Emit(OpCodes.Ldloc, localVar[k]);
             if (pi[k].ParameterType != parameters[k] && parameters[k].IsValueType)
                 il.Emit(OpCodes.Box, parameters[k]);
             il.FreeLocal(localVar[k]);
         }
     }
     else
     {
         methodInfo = inst.GetMethod(name, null);
         if (methodInfo == null)
             throw new ArgumentException("Method not found in class", name);
     }
     il.Emit(OpCodes.Callvirt, methodInfo);
     Type resType = methodInfo.GetReturnType();
     if (resType == typeof(System.Boolean))
     { // Implict boolean convertion
         Label l_false = il.DefineLabel();
         Label end = il.DefineLabel();
         il.Emit(OpCodes.Brfalse_S, l_false);
         il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
         il.Emit(OpCodes.Br_S, end);
         il.MarkLabel(l_false);
         il.EmitNull();
         il.MarkLabel(end);
         st.Push(typeof(System.Object));
     }
     else if (resType == typeof(void))
     { // assume that all procedures returns t
         il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
         st.Push(typeof(System.Object));
     }
     else
         st.Push(resType);
 }
Beispiel #21
0
 public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes)
 {
     if (_implictExecutive)
     {
         LocalBuilder[] localVar = new LocalBuilder[parameterTypes.Length];
         for (int k = localVar.Length - 1; k >= 0; k--)
         {
             localVar[k] = il.DeclareLocal(parameterTypes[k]);
             il.Emit(OpCodes.Stloc, localVar[k]);
         }
         il.Emit(OpCodes.Ldarg_0);
         il.EmitPropertyGet(typeof(CompiledLambda), "Engine");
         for (int k = 0; k < localVar.Length; k++)
         {
             il.Emit(OpCodes.Ldloc, localVar[k]);
             il.FreeLocal(localVar[k]);
         }                
     }
     if (Name.VariableLength)
     {
         LocalBuilder[] localVar = new LocalBuilder[parameterTypes.Length - Name.Arity + 1];
         for (int k = 0; k < localVar.Length; k++)
         {
             if (parameterTypes[k + Name.Arity - 1] != Name.VariableParamType &&
                 Name.VariableParamType != typeof(System.Object))
                 throw new InvalidOperationException();
             localVar[localVar.Length - k -1] = il.DeclareLocal(parameterTypes[k + Name.Arity - 1]);
             il.Emit(OpCodes.Stloc, localVar[localVar.Length - k - 1]);
         }
         il.EmitInt(localVar.Length);
         il.Emit(OpCodes.Newarr, Name.VariableParamType);
         for (int k = 0; k < localVar.Length; k++)
         {
             il.Emit(OpCodes.Dup);
             il.EmitInt(k);
             il.Emit(OpCodes.Ldloc, localVar[k]);
             if (localVar[k].LocalType != Name.VariableParamType &&
                 localVar[k].LocalType.IsValueType)
                 il.Emit(OpCodes.Box, localVar[k].LocalType);
             il.EmitStoreElement(Name.VariableParamType);
             il.FreeLocal(localVar[k]);
         }
     }
     il.EmitCall(_methodInfo);
     return _methodInfo.GetReturnType();
 }
Beispiel #22
0
 public override void CreateVariables(Executive engine, object form, ILGen il, LocalAccess locals, object[] args)
 {
     return;
 }
Beispiel #23
0
 public override void Compile(Executive engine, ILGen il, LocalAccess locals, Type sourceType)
 {
     if (_opcode != OpCodes.Nop)
         il.Emit(_opcode);
 }
Beispiel #24
0
 abstract public void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args);
Beispiel #25
0
 public virtual void CreateVariables(Executive engine, object form, ILGen il, LocalAccess locals, object[] args)
 {
     foreach (object arg in args)
         engine.CreateVariables(il, locals, arg);
 }
Beispiel #26
0
 /// <summary>
 /// Execute function
 /// </summary>
 /// <param name="engine">Calling executive</param>
 /// <param name="args">Argument values</param>
 /// <param name="context">Current context</param>
 /// <returns>Result value</returns>
 abstract public Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes);
Beispiel #27
0
        public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes)
        {  
            if (_compiledBody.Value == null && !_compiled)
            {
                _compiled = true;
                Resolver resolver = null;
                if (Isolate)
                {
                    resolver = engine.Resolver;
                    if (resolver != null)
                        engine.Enter(resolver.NewScope());
                }
                engine.Compile(_parameters, _body, _compiledBody);
                if (resolver != null)
                    engine.Leave();
            }
            locals.AddDependence(this);

            LocalBuilder[] localVar = new LocalBuilder[parameterTypes.Length];
            for (int k = parameterTypes.Length - 1; k >= 0; k--)
            {
                localVar[k] = il.DeclareLocal(parameterTypes[k]);
                il.Emit(OpCodes.Stloc, localVar[k]);
            }
            
            il.Emit(OpCodes.Ldarg_0);
            il.EmitPropertyGet(typeof(CompiledLambda), "Engine");

            il.Emit(OpCodes.Ldarg_1);
            il.EmitInt(locals.DefineConstant(Name.ID));
            il.Emit(OpCodes.Ldelem_Ref);

            il.Emit(OpCodes.Ldarg_1);
            il.EmitInt(locals.DefineConstant(_parameters));
            il.Emit(OpCodes.Ldelem_Ref);
            il.Emit(OpCodes.Isinst, typeof(Executive.Parameter[]));

            il.Emit(OpCodes.Ldarg_1);
            il.EmitInt(locals.DefineConstant(_body));
            il.Emit(OpCodes.Ldelem_Ref);

            il.EmitInt(Name.Arity);
            il.Emit(OpCodes.Newarr, typeof(System.Object));
            for (int k = 0; k < Name.Arity; k++)
            {
                il.Emit(OpCodes.Dup);
                il.EmitInt(k);
                if (!Name.VariableLength || k < Name.Arity - 1)
                {
                    il.Emit(OpCodes.Ldloc, localVar[k]);
                    if (localVar[k].LocalType.IsValueType)
                        il.Emit(OpCodes.Box, localVar[k].LocalType);
                    il.FreeLocal(localVar[k]);
                }
                else
                {
                    il.EmitInt(localVar.Length - k);
                    il.Emit(OpCodes.Newarr, Name.VariableParamType);
                    for (int s = k; s < localVar.Length; s++)
                    {
                        il.Emit(OpCodes.Dup);
                        il.EmitInt(s - k);
                        il.Emit(OpCodes.Ldloc, localVar[s]);
                        if (localVar[s].LocalType != Name.VariableParamType &&
                            localVar[s].LocalType.IsValueType)
                            il.Emit(OpCodes.Box, localVar[s].LocalType);
                        il.EmitStoreElement(Name.VariableParamType);
                        il.FreeLocal(localVar[s]);
                    }
                    il.EmitCall(typeof(Lisp), "List");
                }
                il.EmitStoreElement(typeof(System.Object));
            }

            il.Emit(OpCodes.Ldarg_1);
            il.EmitInt(locals.DefineConstant(_compiledBody));
            il.Emit(OpCodes.Ldelem_Ref);
            il.Emit(OpCodes.Isinst, typeof(FunctionLink));            
            if (Isolate)
            {
                il.Emit(OpCodes.Ldarg_1);
                il.EmitInt(locals.DefineConstant(engine.DefaultPool));
                il.Emit(OpCodes.Ldelem_Ref);
                il.EmitCall(_clonePool);
            }
            else
                il.Emit(OpCodes.Ldarg_3); // MemoryPool
            il.EmitCall(_apply);
            return _retType;            
        }