private static IExpression CreateForwardingCall( IMethod Callee, IMethod Caller) { var thunkParams = Caller.GetParameters(); var args = new IExpression[thunkParams.Length]; for (int i = 0; i < args.Length; i++) { args[i] = new ArgumentVariable(thunkParams[i], i).CreateGetExpression(); } return(new InvocationExpression(Callee, null, args)); }
public override ActionStatus OnUpdate() { var type = Utility.GetType(m_ComponentName); if (type == null) { Debug.LogWarning("Unable to invoke - type is null"); return(ActionStatus.Failure); } var component = this.m_TargetObject.GetComponent(type); if (component == null) { Debug.LogWarning("Unable to invoke with component " + m_ComponentName); return(ActionStatus.Failure); } List <object> parameterList = new List <object>(); List <Type> typeList = new List <Type>(); for (int i = 0; i < m_Arguments.Count; i++) { ArgumentVariable argument = m_Arguments[i]; if (!argument.IsNone) { object value = argument.GetValue(); parameterList.Add(value); typeList.Add(value.GetType()); } } var methodInfo = component.GetType().GetMethod(this.m_MethodName, typeList.ToArray()); if (methodInfo == null) { Debug.LogWarning("Unable to invoke method " + this.m_MethodName + " on component " + this.m_ComponentName); return(ActionStatus.Failure); } bool?result = methodInfo.Invoke(component, parameterList.ToArray()) as bool?; if (result != null && !(bool)result) { if (!string.IsNullOrEmpty(this.m_FailureNotification.text)) { this.m_FailureNotification.Show(); } return(ActionStatus.Failure); } return(ActionStatus.Success); }
public override ActionStatus OnUpdate() { var type = Utility.GetType(m_ComponentName); if (type == null) { Debug.LogWarning("Unable to invoke - type is null"); return(ActionStatus.Failure); } var component = this.m_TargetObject.GetComponent(type); if (component == null) { Debug.LogWarning("Unable to invoke with component " + m_ComponentName); return(ActionStatus.Failure); } List <object> parameterList = new List <object>(); List <Type> typeList = new List <Type>(); for (int i = 0; i < m_Arguments.Count; i++) { ArgumentVariable argument = m_Arguments[i]; if (!argument.IsNone) { object value = argument.GetValue(); parameterList.Add(value); typeList.Add(value.GetType()); } } var methodInfo = component.GetType().GetMethod(this.m_MethodName, typeList.ToArray()); if (methodInfo == null) { Debug.LogWarning("Unable to invoke method " + this.m_MethodName + " on component " + this.m_ComponentName); return(ActionStatus.Failure); } float result = System.Convert.ToSingle(methodInfo.Invoke(component, parameterList.ToArray())); if (this.m_Condition == Condition.Greater && result < this.m_Number || this.m_Condition == Condition.Less && result > this.m_Number) { this.m_FailureNotification.Show(); return(ActionStatus.Failure); } return(ActionStatus.Success); }
/// <summary> /// Auto-implements this method. /// </summary> private IStatement AutoImplement() { var delegateAttribute = ParentType.GetAttribute( MethodType.DelegateAttributeType) as IntrinsicAttribute; string methodName = PreMangledName.Unmangle(Name).ToString(); var parameters = this.GetParameters(); if (delegateAttribute != null && delegateAttribute.Arguments[0].GetValue <string>() == methodName) { // Implement this method using a simple invocation expression. var args = new IExpression[parameters.Length]; for (int i = 0; i < args.Length; i++) { args[i] = new ArgumentVariable(parameters[i], i).CreateGetExpression(); } return(new ReturnStatement( new InvocationExpression( new ReinterpretCastExpression( new ThisVariable(DeclaringType).CreateGetExpression(), MethodType.Create(this)), args))); } else if (methodName == "LoadDelegateHasContextInternal" && IsStatic && ReturnType == PrimitiveTypes.Boolean && parameters.Length == 1) { return(new ReturnStatement( LLVMCodeGenerator.ToExpression( new UnaryBlock( codeGenerator, (CodeBlock) new ArgumentVariable(parameters[0], 0) .CreateGetExpression() .Emit(codeGenerator), PrimitiveTypes.Boolean, DelegateBlock.BuildLoadHasContext)))); } else if (methodName == "LoadDelegateFunctionPointerInternal" && IsStatic && ReturnType.GetIsPointer() && parameters.Length == 1) { return(new ReturnStatement( LLVMCodeGenerator.ToExpression( new UnaryBlock( codeGenerator, (CodeBlock) new ArgumentVariable(parameters[0], 0) .CreateGetExpression() .Emit(codeGenerator), ReturnType, DelegateBlock.BuildLoadFunctionPointer)))); } else if (methodName == "CompareExchange" && IsStatic && parameters.Length == 3) { return(new ReturnStatement( LLVMCodeGenerator.ToExpression( new CompareExchangeBlock( (CodeBlock) new ArgumentVariable(parameters[0], 0) .CreateGetExpression() .Emit(codeGenerator), (CodeBlock) new ArgumentVariable(parameters[1], 1) .CreateGetExpression() .Emit(codeGenerator), (CodeBlock) new ArgumentVariable(parameters[2], 2) .CreateGetExpression() .Emit(codeGenerator), codeGenerator)))); } else if (methodName.StartsWith("AtomicRMW") && IsStatic && parameters.Length == 2) { return(new ReturnStatement( LLVMCodeGenerator.ToExpression( new ReadModifyWriteBlock( (CodeBlock) new ArgumentVariable(parameters[0], 0) .CreateGetExpression() .Emit(codeGenerator), (CodeBlock) new ArgumentVariable(parameters[1], 1) .CreateGetExpression() .Emit(codeGenerator), ReadModifyWriteBlock.ParseOperator( methodName.Substring("AtomicRMW".Length)), codeGenerator)))); } else { throw new NotSupportedException( "Runtime doesn't know how to implement method '" + this.FullName.ToString() + "'."); } }
private static IReadOnlyDictionary<string, IVariable> GetParameters(IMethod Value) { var dict = new Dictionary<string, IVariable>(); if (Value != null) { if (!Value.IsStatic && Value.DeclaringType != null) { dict[CodeSymbols.This.Name] = ThisReferenceVariable.Instance.Create(Value.DeclaringType); } var parameters = Value.GetParameters(); for (int i = 0; i < parameters.Length; i++) { var arg = new ArgumentVariable(parameters[i], i); if (parameters[i].ParameterType.GetIsPointer() && parameters[i].ParameterType.AsContainerType().AsPointerType().PointerKind.Equals(PointerKind.ReferencePointer)) { dict[parameters[i].Name] = new AtAddressVariable(arg.CreateGetExpression()); } else { dict[parameters[i].Name] = arg; } } return dict; } return dict; }
public override void Stage2RoutineBody() { var integer = Context.TypeSystem.Integer; var str = Context.TypeSystem.String; // add { var method = IntrinsicAdd; var ip = method.NativeMethod.Body.GetILProcessor(); var result = new BodyVariable(integer); method.NativeMethod.Body.InitLocals = true; // var result; // value type used by ref result.LoadA(ip); // lhs.value ip.Emit(OpCodes.Ldarg_0); ip.Emit(OpCodes.Ldfld, integer.ValueField); // rhs.value ip.Emit(OpCodes.Ldarg_1); ip.Emit(OpCodes.Ldfld, integer.ValueField); // lhs.value + rhs.value ip.Emit(OpCodes.Add); // result = new SLang$Integer(...) ip.Emit(OpCodes.Call, integer.Ctor); // return result result.Load(ip); ip.Emit(OpCodes.Ret); } // sub { var method = IntrinsicSub; var ip = method.NativeMethod.Body.GetILProcessor(); var result = new BodyVariable(integer); method.NativeMethod.Body.InitLocals = true; // var result; // value type used by ref result.LoadA(ip); // lhs.value ip.Emit(OpCodes.Ldarg_0); ip.Emit(OpCodes.Ldfld, integer.ValueField); // rhs.value ip.Emit(OpCodes.Ldarg_1); ip.Emit(OpCodes.Ldfld, integer.ValueField); // lhs.value - rhs.value ip.Emit(OpCodes.Sub); // result = new SLang$Integer(...) ip.Emit(OpCodes.Call, integer.Ctor); // return result result.Load(ip); ip.Emit(OpCodes.Ret); } // neg { var method = IntrinsicNeg; var ip = method.NativeMethod.Body.GetILProcessor(); var v = new BodyVariable(integer); method.NativeMethod.Body.InitLocals = true; // var result; // value type used by ref v.LoadA(ip); // self.value ip.Emit(OpCodes.Ldarg_0); ip.Emit(OpCodes.Ldfld, integer.ValueField); // -self.value ip.Emit(OpCodes.Neg); // result = new SLang$Integer(...) ip.Emit(OpCodes.Call, integer.Ctor); // return result v.Load(ip); ip.Emit(OpCodes.Ret); } // not { var method = IntrinsicNot; var ip = method.NativeMethod.Body.GetILProcessor(); var arg = new ArgumentVariable(integer, 0); // prepare argument arg.Load(ip); integer.Unboxed(ip); // prepare zero ip.Emit(OpCodes.Ldc_I4_0); // result = (arg == 0); ip.Emit(OpCodes.Ceq); var result = integer.Boxed(ip); // return result; result.Load(ip); ip.Emit(OpCodes.Ret); } // less than { var method = IntrinsicLessThan; var ip = method.NativeMethod.Body.GetILProcessor(); var lhs = new ArgumentVariable(integer, 0); var rhs = new ArgumentVariable(integer, 1); // prepare lhs lhs.Load(ip); integer.Unboxed(ip); // prepare rhs rhs.Load(ip); integer.Unboxed(ip); // result = lhs < rhs; ip.Emit(OpCodes.Clt); var result = integer.Boxed(ip); // return result; result.Load(ip); ip.Emit(OpCodes.Ret); } // greater than { var method = IntrinsicGreaterThan; var ip = method.NativeMethod.Body.GetILProcessor(); var lhs = new ArgumentVariable(integer, 0); var rhs = new ArgumentVariable(integer, 1); // prepare lhs lhs.Load(ip); integer.Unboxed(ip); // prepare rhs rhs.Load(ip); integer.Unboxed(ip); // result = lhs > rhs; ip.Emit(OpCodes.Cgt); var result = integer.Boxed(ip); // return result; result.Load(ip); ip.Emit(OpCodes.Ret); } // equal { var method = IntrinsicEqual; var ip = method.NativeMethod.Body.GetILProcessor(); var lhs = new ArgumentVariable(integer, 0); var rhs = new ArgumentVariable(integer, 1); // prepare lhs lhs.Load(ip); integer.Unboxed(ip); // prepare rhs rhs.Load(ip); integer.Unboxed(ip); // result = (lhs == rhs); ip.Emit(OpCodes.Ceq); var result = integer.Boxed(ip); // return result; result.Load(ip); ip.Emit(OpCodes.Ret); } // StandardIO$put$Integer { // direct proxy to void Console.Write(Int32) var method = StandardIO_put_Integer; var ip = method.NativeMethod.Body.GetILProcessor(); var writeForeign = consoleNativeType.Methods.Single( m => m.Name == nameof(Console.Write) && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.Name == Context.TypeSystem.Integer.WrappedNativeType.Name); var writeImported = Context.NativeModule.ImportReference(writeForeign); // unbox argument new ArgumentVariable(integer, 0).Load(ip); integer.Unboxed(ip); // call method ip.Emit(OpCodes.Call, writeImported); // return nothing ip.Emit(OpCodes.Ret); } // StandardIO$put$String { // direct proxy to void Console.Write(String) var method = StandardIO_put_String; var ip = method.NativeMethod.Body.GetILProcessor(); var writeForeign = consoleNativeType.Methods.Single( m => m.Name == nameof(Console.Write) && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.Name == Context.TypeSystem.String.WrappedNativeType.Name); var writeImported = Context.NativeModule.ImportReference(writeForeign); // unbox argument new ArgumentVariable(str, 0).Load(ip); str.Unboxed(ip); // call method ip.Emit(OpCodes.Call, writeImported); // return nothing ip.Emit(OpCodes.Ret); } base.Stage2RoutineBody(); }