Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 4
0
        /// <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;
        }
Exemplo n.º 6
0
        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();
        }