private Expression /*!*/ MarshalArgument(MetaObjectBuilder /*!*/ metaBuilder, DynamicMetaObject /*!*/ arg, ArgType parameterType) { object value = arg.Value; if (value == null) { metaBuilder.AddRestriction(Ast.Equal(arg.Expression, AstUtils.Constant(null))); } else { metaBuilder.AddTypeRestriction(value.GetType(), arg.Expression); } switch (parameterType) { case ArgType.Buffer: if (value == null) { return(AstUtils.Constant(null, typeof(byte[]))); } if (value is int && (int)value == 0) { metaBuilder.AddRestriction(Ast.Equal(AstUtils.Convert(arg.Expression, typeof(int)), AstUtils.Constant(0))); return(AstUtils.Constant(null, typeof(byte[]))); } if (value.GetType() == typeof(MutableString)) { return(Methods.GetMutableStringBytes.OpCall( AstUtils.Convert(arg.Expression, typeof(MutableString)) )); } return(Methods.GetMutableStringBytes.OpCall( AstUtils.LightDynamic(ConvertToStrAction.Make(_context), typeof(MutableString), arg.Expression) )); case ArgType.Int32: if (value is int) { return(AstUtils.Convert(arg.Expression, typeof(int))); } return(Ast.Convert( Ast.Call( AstUtils.LightDynamic(ConvertToIntAction.Make(_context), typeof(IntegerValue), arg.Expression), Methods.IntegerValue_ToUInt32Unchecked ), typeof(int) )); } throw Assert.Unreachable; }
internal static void BuildConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { const string ToS = "to_s"; if (TryImplicitConversion(metaBuilder, args)) { metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression); return; } RubyMemberInfo conversionMethod, methodMissing = null; RubyClass targetClass = args.RubyContext.GetImmediateClassOf(args.Target); using (targetClass.Context.ClassHierarchyLocker()) { metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext, new[] { ToS, Symbols.MethodMissing } ); conversionMethod = targetClass.ResolveMethodForSiteNoLock(ToS, VisibilityContext.AllVisible).Info; // find method_missing - we need to add "to_s" method to the missing methods table: if (conversionMethod == null) { methodMissing = targetClass.ResolveMethodMissingForSite(ToS, RubyMethodVisibility.None); } } // invoke target.to_s and if successful convert the result to string unless it is already: if (conversionMethod != null) { conversionMethod.BuildCall(metaBuilder, args, ToS); } else { RubyCallAction.BuildMethodMissingCall(metaBuilder, args, ToS, methodMissing, RubyMethodVisibility.None, false, true); } if (metaBuilder.Error) { return; } metaBuilder.Result = Methods.ToSDefaultConversion.OpCall( AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)), AstUtils.Box(args.TargetExpression), AstUtils.Box(metaBuilder.Result) ); }
internal void BuildInvoke(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { Assert.NotNull(metaBuilder, args); var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(Proc)); // test for target type: metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression); BuildCall( metaBuilder, convertedTarget, // proc object Methods.GetProcSelf.OpCall(convertedTarget), // self captured by the block closure args ); }
/// <summary> /// OldCallAction on Proc target. /// From control flow perspective it "yields" to the proc. /// </summary> internal void SetCallActionRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { Assert.NotNull(metaBuilder, args); Debug.Assert(!args.Signature.HasBlock); var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(BlockParam)); // test for target type: metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression); metaBuilder.Result = AstFactory.YieldExpression( args.GetSimpleArgumentExpressions(), args.GetSplattedArgumentExpression(), args.GetRhsArgumentExpression(), convertedTarget, // block param Ast.Property(convertedTarget, SelfProperty) // self ); }
internal static void SetCallActionRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, bool testTarget) { Assert.NotNull(metaBuilder, args); var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(Proc)); // test for target type: if (testTarget) { metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression); } SetProcCallRule( metaBuilder, convertedTarget, // proc object Ast.Property(convertedTarget, SelfProperty), // self captured by the block closure null, args ); }