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)); }
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); }
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); }
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)); }
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); }
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); } } }
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)); }
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); }
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(); }
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(); }
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)); }
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)); }
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; }
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(); }
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); } }
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"); }
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 }
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); } }
public override void Compile(Executive engine, ILGen il, LocalAccess locals, Type sourceType) { il.EmitCall(_methodInfo[sourceType]); }
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); }
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(); }
public override void CreateVariables(Executive engine, object form, ILGen il, LocalAccess locals, object[] args) { return; }
public override void Compile(Executive engine, ILGen il, LocalAccess locals, Type sourceType) { if (_opcode != OpCodes.Nop) il.Emit(_opcode); }
abstract public void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args);
public virtual void CreateVariables(Executive engine, object form, ILGen il, LocalAccess locals, object[] args) { foreach (object arg in args) engine.CreateVariables(il, locals, arg); }
/// <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);
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; }