Exemplo n.º 1
0
 internal SuperCallAction(RubyContext context, RubyCallSignature signature, int lexicalScopeId)
     : base(context)
 {
     Debug.Assert(signature.HasImplicitSelf && signature.HasScope && (signature.HasBlock || signature.ResolveOnly));
     _signature = signature;
     _lexicalScopeId = lexicalScopeId;
 }
Exemplo n.º 2
0
        // Ruby binders:
        internal CallArguments(RubyContext context, DynamicMetaObject/*!*/ scopeOrContextOrTargetOrArgArray, DynamicMetaObject/*!*/[]/*!*/ args, RubyCallSignature signature)
        {
            Assert.NotNull(scopeOrContextOrTargetOrArgArray);
            Assert.NotNullItems(args);

            ArgumentArray argArray = scopeOrContextOrTargetOrArgArray.Value as ArgumentArray;
            if (argArray != null) {
                Debug.Assert(args.Length == 0 && argArray.Count >= 1);

                // build meta-objects for arguments wrapped in the array:
                args = new DynamicMetaObject[argArray.Count - 1];
                for (int i = 0; i < args.Length; i++) {
                    args[i] = argArray.GetMetaObject(scopeOrContextOrTargetOrArgArray.Expression, 1 + i);
                }
                scopeOrContextOrTargetOrArgArray = argArray.GetMetaObject(scopeOrContextOrTargetOrArgArray.Expression, 0);
            }

            Debug.Assert(signature.HasScope == scopeOrContextOrTargetOrArgArray.Value is RubyScope);
            Debug.Assert((context == null && !signature.HasScope) == scopeOrContextOrTargetOrArgArray.Value is RubyContext);

            if (context != null) {
                // bound site:
                _context = new DynamicMetaObject(AstUtils.Constant(context), BindingRestrictions.Empty, context);
                if (signature.HasScope) {
                    _scope = scopeOrContextOrTargetOrArgArray;
                    _hasScopeOrContextArg = true;
                } else {
                    _target = scopeOrContextOrTargetOrArgArray;
                }
            } else if (signature.HasScope) {
                // unbound site with scope:
                _context = new DynamicMetaObject(
                    Methods.GetContextFromScope.OpCall(scopeOrContextOrTargetOrArgArray.Expression), BindingRestrictions.Empty,
                    ((RubyScope)scopeOrContextOrTargetOrArgArray.Value).RubyContext
                );
                _scope = scopeOrContextOrTargetOrArgArray;
                _hasScopeOrContextArg = true;
                _target = null;
            } else {
                // unbound site with context:
                _context = scopeOrContextOrTargetOrArgArray;
                _hasScopeOrContextArg = true;
                _target = null;
            }

            Debug.Assert(_target != null || args.Length > 0);

            _args = args;
            _copyArgsOnWrite = true;
            _signature = signature;

            Debug.Assert(!signature.HasSplattedArgument || GetSplattedArgument() != null);
        }
Exemplo n.º 3
0
        internal override MemberDispatcher GetDispatcher(Type/*!*/ delegateType, RubyCallSignature signature, object target, int version) {
            if (!(target is IRubyObject)) {
                return null;
            } 
            
            if (signature.ArgumentCount != 0 || signature.HasRhsArgument || signature.HasBlock || !signature.HasScope) {
                return null;
            }

            var dispatcher = new RubyObjectAttributeReaderDispatcherWithScope();
            dispatcher.Initialize(InstanceVariableName, version);
            return dispatcher;
        }
Exemplo n.º 4
0
        internal protected RubyCallAction(RubyContext context, string/*!*/ methodName, RubyCallSignature signature) 
            : base(context) {
            Assert.NotNull(methodName);
            
            // a virtual call cannot be a super call nor interop call:
            Debug.Assert(!signature.IsVirtualCall || !signature.IsSuperCall && !signature.IsInteropCall);

            // a super call must have implicit self:
            Debug.Assert(!signature.IsSuperCall || signature.HasImplicitSelf);

            _methodName = methodName;
            _signature = signature;
        }
Exemplo n.º 5
0
        internal static MSA.DynamicExpression/*!*/ InvokeMethod(RubyContext/*!*/ context, string/*!*/ name, RubyCallSignature signature,
            params MSA.Expression[]/*!*/ args) {

            Debug.Assert(args.Length >= 2);
            var scope = args[0];
            var target = args[1];

            switch (args.Length) {
                case 2: return InvokeMethod(context, name, signature, scope, target);
                case 3: return InvokeMethod(context, name, signature, scope, target, args[2]);
                case 4: return InvokeMethod(context, name, signature, scope, target, args[2], args[3]);
                default: return InvokeMethod(context, name, signature, scope, target, args);
            }
        }
Exemplo n.º 6
0
 private static MSA.DynamicExpression/*!*/ MakeCallAction(RubyContext/*!*/ context, string/*!*/ name, RubyCallSignature signature, 
     params MSA.Expression[]/*!*/ args) {
     RubyCallAction call = RubyCallAction.Make(context, name, signature);
     switch (args.Length) {
         case 0: return Ast.Dynamic(call, typeof(object), AstFactory.EmptyExpressions);
         case 1: return Ast.Dynamic(call, typeof(object), args[0]);
         case 2: return Ast.Dynamic(call, typeof(object), args[0], args[1]);
         case 3: return Ast.Dynamic(call, typeof(object), args[0], args[1], args[2]);
         case 4: return Ast.Dynamic(call, typeof(object), args[0], args[1], args[2], args[3]);
         default:
             return Ast.Dynamic(
                 call,
                 typeof(object),
                 new ReadOnlyCollection<MSA.Expression>(args)
             );
     }
 }
Exemplo n.º 7
0
        internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen)
        {
            Debug.Assert(gen != null);

            ScopeBuilder scope = DefineLocals();

            MSA.ParameterExpression[] parameters;
            MSA.ParameterExpression   selfVariable;
            MSA.ParameterExpression   runtimeScopeVariable;
            MSA.ParameterExpression   blockParameter;

            if (gen.CompilerOptions.FactoryKind == TopScopeFactoryKind.None ||
                gen.CompilerOptions.FactoryKind == TopScopeFactoryKind.ModuleEval)
            {
                parameters = new MSA.ParameterExpression[4];

                runtimeScopeVariable = parameters[0] = Ast.Parameter(typeof(RubyScope), "#scope");
                selfVariable         = parameters[1] = Ast.Parameter(typeof(object), "#self");
                parameters[2]        = Ast.Parameter(typeof(RubyModule), "#module");
                blockParameter       = parameters[3] = Ast.Parameter(typeof(Proc), "#block");
            }
            else
            {
                parameters = new MSA.ParameterExpression[2];

                runtimeScopeVariable = parameters[0] = Ast.Parameter(typeof(RubyScope), "#scope");
                selfVariable         = parameters[1] = Ast.Parameter(typeof(object), "#self");

                blockParameter = null;
            }

            gen.EnterSourceUnit(
                scope,
                selfVariable,
                runtimeScopeVariable,
                blockParameter,
                gen.CompilerOptions.TopLevelMethodName, // method name for blocks
                null                                    // parameters for super calls
                );

            MSA.Expression body;

            if (_statements.Count > 0)
            {
                if (gen.PrintInteractiveResult)
                {
                    var resultVariable = scope.DefineHiddenVariable("#result", typeof(object));

                    var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable,
                                                                         AstUtils.LightDynamic(ConvertToSAction.Make(gen.Context), typeof(MutableString),
                                                                                               CallSiteBuilder.InvokeMethod(gen.Context, "inspect", RubyCallSignature.WithScope(0),
                                                                                                                            gen.CurrentScopeVariable, resultVariable
                                                                                                                            )
                                                                                               )
                                                                         );

                    body = gen.TransformStatements(null, _statements, epilogue, ResultOperation.Store(resultVariable));
                }
                else
                {
                    body = gen.TransformStatements(_statements, ResultOperation.Return);
                }

                // TODO:
                var exceptionVariable = Ast.Parameter(typeof(Exception), "#exception");
                body = AstUtils.Try(
                    body
                    ).Filter(exceptionVariable, Methods.TraceTopLevelCodeFrame.OpCall(runtimeScopeVariable, exceptionVariable),
                             Ast.Empty()
                             );
            }
            else
            {
                body = AstUtils.Constant(null);
            }

            // scope initialization:
            MSA.Expression prologue;
            switch (gen.CompilerOptions.FactoryKind)
            {
            case TopScopeFactoryKind.None:
            case TopScopeFactoryKind.ModuleEval:
                prologue = Methods.InitializeScopeNoLocals.OpCall(runtimeScopeVariable, EnterInterpretedFrameExpression.Instance);
                break;

            case TopScopeFactoryKind.Hosted:
            case TopScopeFactoryKind.File:
            case TopScopeFactoryKind.WrappedFile:
                prologue = Methods.InitializeScope.OpCall(
                    runtimeScopeVariable, scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(),
                    EnterInterpretedFrameExpression.Instance
                    );
                break;

            case TopScopeFactoryKind.Main:
                prologue = Methods.InitializeScope.OpCall(
                    runtimeScopeVariable, scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(),
                    EnterInterpretedFrameExpression.Instance
                    );
                if (_dataOffset >= 0)
                {
                    prologue = Ast.Block(
                        prologue,
                        Methods.SetDataConstant.OpCall(
                            runtimeScopeVariable,
                            gen.SourcePathConstant,
                            AstUtils.Constant(_dataOffset)
                            )
                        );
                }
                break;

            default:
                throw Assert.Unreachable;
            }

            // BEGIN blocks:
            if (gen.FileInitializers != null)
            {
                var b = new AstBlock();
                b.Add(prologue);
                b.Add(gen.FileInitializers);
                b.Add(body);
                body = b;
            }

            body = gen.AddReturnTarget(scope.CreateScope(body));

            gen.LeaveSourceUnit();

            return(Ast.Lambda <T>(body, GetEncodedName(gen), parameters));
        }
Exemplo n.º 8
0
 private static VisibilityContext GetVisibilityContext(RubyCallSignature callSignature, RubyScope scope) {
     return callSignature.HasImplicitSelf || !callSignature.HasScope ? 
         new VisibilityContext(callSignature.IsInteropCall ? RubyMethodAttributes.Public : RubyMethodAttributes.VisibilityMask) :
         new VisibilityContext(scope.SelfImmediateClass);
 }
Exemplo n.º 9
0
        // interop binders: the target is a Ruby meta-object closed over the context
        internal CallArguments(DynamicMetaObject/*!*/ context, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, RubyCallSignature signature) {
            Assert.NotNull(target, context);
            Assert.NotNullItems(args);

            Debug.Assert(!signature.HasScope && !signature.HasSplattedArgument);

            _target = target;
            _context = context;
            _args = args;
            _copyArgsOnWrite = true;
            _signature = signature;
        }
Exemplo n.º 10
0
        internal CallArguments(DynamicMetaObject/*!*/ context, DynamicMetaObject/*!*/[]/*!*/ args, RubyCallSignature signature) {
            Assert.NotNull(context);
            Assert.NotNullItems(args);
            Assert.NotEmpty(args);

            Debug.Assert(signature.HasScope == context.Value is RubyScope);
            Debug.Assert(!signature.HasScope == context.Value is RubyContext);
            
            _target = null;
            _context = context;
            _args = args;
            _copyArgsOnWrite = true;
            _signature = signature;
        }
Exemplo n.º 11
0
        internal override MethodDispatcher GetDispatcher(Type/*!*/ delegateType, RubyCallSignature signature, object target, int version) {
            if (HasUnsplatParameter || OptionalParamCount > 0) {
                return null;
            }

            if (!(target is IRubyObject)) {
                return null;
            }

            return MethodDispatcher.CreateRubyObjectDispatcher(
                delegateType, GetDelegate(), MandatoryParamCount, signature.HasScope, signature.HasBlock, version
            );
        }
Exemplo n.º 12
0
 public static RubyCallAction InstanceCallAction(string/*!*/ name, RubyCallSignature callSignature) {
     return RubyCallAction.Make(name, callSignature);
 }
Exemplo n.º 13
0
 /*!*/
 public static SuperCallAction Make(RubyContext/*!*/ context, RubyCallSignature signature, int lexicalScopeId)
 {
     ContractUtils.RequiresNotNull(context, "context");
     return context.MetaBinderFactory.SuperCall(lexicalScopeId, signature);
 }
Exemplo n.º 14
0
 // when <expr>
 //   generates into:
 //   RubyOps.IsTrue(<expr>) if the case has no value, otherise:
 //   RubyOps.IsTrue(Call("===", <expr>, <value>))
 private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, Expression /*!*/ expr, MSA.Expression value)
 {
     MSA.Expression transformedExpr = expr.TransformRead(gen);
     if (expr is SplattedArgument)
     {
         if (value != null)
         {
             return(Methods.ExistsUnsplatCompare.OpCall(
                        Ast.Constant(CallSite <Func <CallSite, object, object, object> > .Create(
                                         RubyCallAction.Make(gen.Context, "===", RubyCallSignature.WithImplicitSelf(2))
                                         )),
                        AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr),
                        AstUtils.Box(value)
                        ));
         }
         else
         {
             return(Methods.ExistsUnsplat.OpCall(
                        AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr)
                        ));
         }
     }
     else
     {
         if (value != null)
         {
             return(AstFactory.IsTrue(
                        CallSiteBuilder.InvokeMethod(gen.Context, "===", RubyCallSignature.WithScope(1),
                                                     gen.CurrentScopeVariable,
                                                     transformedExpr,
                                                     value
                                                     )
                        ));
         }
         else
         {
             return(AstFactory.IsTrue(transformedExpr));
         }
     }
 }
Exemplo n.º 15
0
 internal protected RubyCallAction(RubyContext context, string/*!*/ methodName, RubyCallSignature signature) 
     : base(context) {
     Assert.NotNull(methodName);
     _methodName = methodName;
     _signature = signature;
 }
Exemplo n.º 16
0
        internal static MSA.DynamicExpression/*!*/ InvokeMethod(RubyContext/*!*/ context, string/*!*/ name, RubyCallSignature signature,
            MSA.Expression/*!*/ scope, MSA.Expression/*!*/ target, MSA.Expression/*!*/ arg0) {
            Debug.Assert(signature.HasScope);

            return Ast.Dynamic(RubyCallAction.Make(context, name, signature), typeof(object), AstUtils.Convert(scope, typeof(RubyScope)), target, arg0);
        }
Exemplo n.º 17
0
        internal static MSA.DynamicExpression/*!*/ InvokeMethod(RubyContext/*!*/ context, string/*!*/ name, RubyCallSignature signature,
            MSA.Expression/*!*/ scope, MSA.Expression/*!*/ target, MSA.Expression/*!*/[]/*!*/ args) {
            Debug.Assert(signature.HasScope);
            Debug.Assert(args.Length >= 2);

            args[0] = Ast.Convert(args[0], typeof(RubyScope));
            return Ast.Dynamic(RubyCallAction.Make(context, name, signature), typeof(object), args);
        }
Exemplo n.º 18
0
        internal static void BuildConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, Type /*!*/ resultType,
                                             params ProtocolConversionAction /*!*/[] /*!*/ conversions)
        {
            Assert.NotNull(metaBuilder, args, conversions);
            Debug.Assert(args.SimpleArgumentCount == 0 && !args.Signature.HasBlock && !args.Signature.HasSplattedArgument && !args.Signature.HasRhsArgument);
            Debug.Assert(!args.Signature.HasScope);

            // implicit conversions should only depend on the static type:
            foreach (var conversion in conversions)
            {
                if (conversion.TryImplicitConversion(metaBuilder, args))
                {
                    metaBuilder.AddObjectTypeRestriction(args.Target, args.TargetExpression);

                    if (!metaBuilder.Error)
                    {
                        metaBuilder.Result = ConvertResult(metaBuilder.Result, resultType);
                    }
                    return;
                }
            }

            RubyClass                targetClass = args.RubyContext.GetImmediateClassOf(args.Target);
            Expression               targetClassNameConstant = AstUtils.Constant(targetClass.GetNonSingletonClass().Name);
            MethodResolutionResult   respondToMethod, methodMissing = MethodResolutionResult.NotFound;
            ProtocolConversionAction selectedConversion = null;
            RubyMemberInfo           conversionMethod   = null;

            using (targetClass.Context.ClassHierarchyLocker()) {
                // check for type version:
                metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext,
                                              ArrayUtils.Insert(Symbols.RespondTo, Symbols.MethodMissing, ArrayUtils.ConvertAll(conversions, (c) => c.ToMethodName))
                                              );

                // we can optimize if Kernel#respond_to? method is not overridden:
                respondToMethod = targetClass.ResolveMethodForSiteNoLock(Symbols.RespondTo, VisibilityContext.AllVisible);
                if (respondToMethod.Found && respondToMethod.Info.DeclaringModule == targetClass.Context.KernelModule && respondToMethod.Info is RubyLibraryMethodInfo)   // TODO: better override detection
                {
                    respondToMethod = MethodResolutionResult.NotFound;

                    // get the first applicable conversion:
                    foreach (var conversion in conversions)
                    {
                        selectedConversion = conversion;
                        conversionMethod   = targetClass.ResolveMethodForSiteNoLock(conversion.ToMethodName, VisibilityContext.AllVisible).Info;
                        if (conversionMethod != null)
                        {
                            break;
                        }
                        else
                        {
                            // find method_missing - we need to add "to_xxx" methods to the missing methods table:
                            if (!methodMissing.Found)
                            {
                                methodMissing = targetClass.ResolveMethodNoLock(Symbols.MethodMissing, VisibilityContext.AllVisible);
                            }
                            methodMissing.InvalidateSitesOnMissingMethodAddition(conversion.ToMethodName, targetClass.Context);
                        }
                    }
                }
            }

            if (!respondToMethod.Found)
            {
                if (conversionMethod == null)
                {
                    // error:
                    selectedConversion.SetError(metaBuilder, args, targetClassNameConstant, resultType);
                    return;
                }
                else
                {
                    // invoke target.to_xxx() and validate it; returns an instance of TTargetType:
                    conversionMethod.BuildCall(metaBuilder, args, selectedConversion.ToMethodName);

                    if (!metaBuilder.Error)
                    {
                        metaBuilder.Result = ConvertResult(
                            selectedConversion.MakeValidatorCall(args, targetClassNameConstant, metaBuilder.Result),
                            resultType
                            );
                    }
                    return;
                }
            }

            // slow path: invoke respond_to?, to_xxx and result validation:
            for (int i = conversions.Length - 1; i >= 0; i--)
            {
                string toMethodName = conversions[i].ToMethodName;

                var conversionCallSite = AstUtils.LightDynamic(
                    RubyCallAction.Make(args.RubyContext, toMethodName, RubyCallSignature.WithImplicitSelf(0)),
                    args.TargetExpression
                    );

                metaBuilder.Result = Ast.Condition(
                    // If

                    // respond_to?()
                    Methods.IsTrue.OpCall(
                        AstUtils.LightDynamic(
                            RubyCallAction.Make(args.RubyContext, Symbols.RespondTo, RubyCallSignature.WithImplicitSelf(1)),
                            args.TargetExpression,
                            Ast.Constant(args.RubyContext.CreateSymbol(toMethodName, RubyEncoding.Binary))
                            )
                        ),

                    // Then

                    // to_xxx():
                    ConvertResult(
                        conversions[i].MakeValidatorCall(args, targetClassNameConstant, conversionCallSite),
                        resultType
                        ),

                    // Else

                    (i < conversions.Length - 1) ? metaBuilder.Result :
                    conversions[i].MakeErrorExpression(args, targetClassNameConstant, resultType)
                    );
            }
        }
Exemplo n.º 19
0
 internal virtual MemberDispatcher GetDispatcher(Type/*!*/ delegateType, RubyCallSignature signature, object target, int version)
 {
     return null;
 }
Exemplo n.º 20
0
 /// <summary>
 /// This is called by the IronRuby runtime to set the backtrace for an exception that has being raised.
 /// Note that the backtrace may be set directly by user code as well. However, that uses a different code path.
 /// </summary>
 private void DynamicSetBacktrace(RubyContext /*!*/ context, RubyArray backtrace)
 {
     if (_setBacktraceCallSite == null)
     {
         Interlocked.CompareExchange(ref _setBacktraceCallSite, CallSite <Func <CallSite, RubyContext, Exception, RubyArray, object> > .
                                     Create(RubyCallAction.MakeShared("set_backtrace", RubyCallSignature.WithImplicitSelf(1))), null);
     }
     _setBacktraceCallSite.Target(_setBacktraceCallSite, context, _exception, backtrace);
 }
Exemplo n.º 21
0
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            Assert.NotNull(gen);

            MSA.Expression transformedBlock = _block.Transform(gen);

            MSA.Expression blockArgVariable = gen.CurrentScope.DefineHiddenVariable("#forloop-block", typeof(Proc));

            MSA.Expression result = CallSiteBuilder.InvokeMethod(gen.Context, "each", RubyCallSignature.WithScopeAndBlock(0),
                                                                 gen.CurrentScopeVariable,
                                                                 _list.TransformRead(gen),
                                                                 blockArgVariable
                                                                 );

            return(gen.DebugMark(MethodCall.MakeCallWithBlockRetryable(gen, result, blockArgVariable, transformedBlock, true),
                                 "#RB: method call with a block ('for-loop')"));
        }
Exemplo n.º 22
0
 public static SuperCallAction MakeShared(RubyCallSignature signature, int lexicalScopeId)
 {
     return RubyMetaBinderFactory.Shared.SuperCall(lexicalScopeId, signature);
 }
Exemplo n.º 23
0
        internal static MSA.Expression /*!*/ InvokeMethod(RubyContext /*!*/ context, string /*!*/ name, RubyCallSignature signature,
                                                          MSA.Expression /*!*/ scope, MSA.Expression /*!*/ target, MSA.Expression /*!*/ arg0, MSA.Expression /*!*/ arg1)
        {
            Debug.Assert(signature.HasScope);

            return(AstUtils.LightDynamic(RubyCallAction.Make(context, name, signature), AstUtils.Convert(scope, typeof(RubyScope)), target, arg0, arg1));
        }
Exemplo n.º 24
0
        internal override MemberDispatcher GetDispatcher(Type/*!*/ delegateType, RubyCallSignature signature, object target, int version) {
            if (Parameters.Unsplat != null || Parameters.Optional.Length > 0) {
                return null;
            }

            if (!(target is IRubyObject)) {
                return null;
            }

            return MethodDispatcher.CreateRubyObjectDispatcher(
                delegateType, GetDelegate(), Parameters.Mandatory.Length, signature.HasScope, signature.HasBlock, version
            );
        }
Exemplo n.º 25
0
 // friend: RubyContext
 internal EqualityComparer(RubyContext /*!*/ context)
     : this(
         CallSite <Func <CallSite, object, object> > .Create(RubyCallAction.Make(context, "hash", RubyCallSignature.WithImplicitSelf(0))),
         CallSite <Func <CallSite, object, object, object> > .Create(RubyCallAction.Make(context, "eql?", RubyCallSignature.WithImplicitSelf(1)))
         )
 {
 }
Exemplo n.º 26
0
        internal override MemberDispatcher GetDispatcher(Type/*!*/ delegateType, RubyCallSignature signature, object target, int version)
        {
            if (!(target is IRubyObject)) {
                return null;
            }

            if (signature.ArgumentCount + (signature.HasRhsArgument ? 1 : 0) != 1 || signature.HasBlock) {
                return null;
            }

            return AttributeDispatcher.CreateRubyObjectWriterDispatcher(delegateType, InstanceVariableName, version);
        }
Exemplo n.º 27
0
 /// <summary>
 /// Creates a runtime-bound call site binder.
 /// </summary>
 public static RubyCallAction/*!*/ Make(RubyContext/*!*/ context, string/*!*/ methodName, RubyCallSignature signature) {
     ContractUtils.RequiresNotNull(context, "context");
     ContractUtils.RequiresNotNull(methodName, "methodName");
     return context.MetaBinderFactory.Call(methodName, signature);
 }
Exemplo n.º 28
0
        // Ruby binders: 
        internal CallArguments(RubyContext context, DynamicMetaObject/*!*/ scopeOrContextOrTarget, DynamicMetaObject/*!*/[]/*!*/ args, RubyCallSignature signature) {
            Assert.NotNull(scopeOrContextOrTarget);
            Assert.NotNullItems(args);

            Debug.Assert(signature.HasScope == scopeOrContextOrTarget.Value is RubyScope);
            Debug.Assert((context == null && !signature.HasScope) == scopeOrContextOrTarget.Value is RubyContext);

            if (context != null) {
                // bound site:
                _context = new DynamicMetaObject(AstUtils.Constant(context), BindingRestrictions.Empty, context);
                if (signature.HasScope) {
                    _scope = scopeOrContextOrTarget;
                    _hasScopeOrContextArg = true;
                } else {
                    _target = scopeOrContextOrTarget;
                }
            } else if (signature.HasScope) {
                // unbound site with scope:
                _context = new DynamicMetaObject(
                    Methods.GetContextFromScope.OpCall(scopeOrContextOrTarget.Expression), BindingRestrictions.Empty, 
                    ((RubyScope)scopeOrContextOrTarget.Value).RubyContext
                );
                _scope = scopeOrContextOrTarget;
                _hasScopeOrContextArg = true;
                _target = null;
            } else {
                // unbound site with context:
                _context = scopeOrContextOrTarget;
                _hasScopeOrContextArg = true;
                _target = null;
            }

            Debug.Assert(_target != null || args.Length > 0);

            _args = args;
            _copyArgsOnWrite = true;
            _signature = signature;

            Debug.Assert(!signature.HasSplattedArgument || GetSplattedArgument() != null);
        }
Exemplo n.º 29
0
 public CallSite <TCallSiteFunc> /*!*/ GetCallSite(string /*!*/ methodName, RubyCallSignature signature)
 {
     return(RubyUtils.GetCallSite(ref Site, Context, methodName, signature));
 }
Exemplo n.º 30
0
        public void InsertSimple(int index, DynamicMetaObject/*!*/ arg) {
            index = GetSimpleArgumentsIndex(index);

            _args = ArrayUtils.InsertAt(_args, index, arg);
            _signature = new RubyCallSignature(_signature.ArgumentCount + 1, _signature.Flags);
        }
Exemplo n.º 31
0
        internal override MethodDispatcher GetDispatcher(Type/*!*/ delegateType, RubyCallSignature signature, object target, int version) {
            if (!(target is IRubyObject)) {
                return null;
            }

            int arity;
            if (!IsEmpty || (arity = GetArity()) != 1) {
                return null;
            }

            return MethodDispatcher.CreateRubyObjectDispatcher(
                delegateType, new Func<object, Proc, object, object>(EmptyRubyMethodStub1), arity, signature.HasScope, signature.HasBlock, version
            );
        }
Exemplo n.º 32
0
 internal SuperCallAction(RubyContext context, RubyCallSignature signature, int lexicalScopeId)
     : base(context) {
     _signature = signature;
     _lexicalScopeId = lexicalScopeId;
 }
Exemplo n.º 33
0
        public void OverloadResolution_Numeric1()
        {
            var metaBuilder = new MetaObjectBuilder(null);

#if FEATURE_REFEMIT
            Context.ObjectClass.SetConstant("X", Context.GetClass(typeof(Overloads1.X)));
            object c = Engine.Execute(@"class C < X; new; end");
#else
            object c = new Overloads1.X();
#endif

            var sym = Context.CreateAsciiSymbol("x");
            var ms  = MutableString.CreateAscii("x");

            var cases = new[] {
                // F
                new { Args = new[] { MO(1) }, OverloadPrefix = "F", Result = "F1" },
                new { Args = new[] { MO((byte)1) }, OverloadPrefix = "F", Result = "F1" },
                new { Args = new[] { MO(1L) }, OverloadPrefix = "F", Result = "F2" },
                new { Args = new[] { MO(1.2F) }, OverloadPrefix = "F", Result = "F3" },

                // G
                new { Args = new[] { MO(1) }, OverloadPrefix = "G", Result = "G1" },
                new { Args = new[] { MO((byte)1) }, OverloadPrefix = "G", Result = "G1" },
                new { Args = new[] { MO(1L) }, OverloadPrefix = "G", Result = "G2" },
                new { Args = new[] { MO(1.2F) }, OverloadPrefix = "G", Result = "G3" },
                new { Args = new[] { MO(c) }, OverloadPrefix = "G", Result = "G1" },

                // I
                new { Args = new[] { MO(c) }, OverloadPrefix = "I", Result = "I3" },

                // J
                new { Args = new[] { MO(1) }, OverloadPrefix = "J", Result = "J1" },
                new { Args = new[] { MO((BigInteger)1000) }, OverloadPrefix = "J", Result = "J2" },
                new { Args = new[] { MO((byte)12) }, OverloadPrefix = "J", Result = "J1" },
                new { Args = new[] { MO(c) }, OverloadPrefix = "J", Result = "J3" },
                new { Args = new[] { MO(1.0) }, OverloadPrefix = "J", Result = "J3" },

                // K
                new { Args = new[] { MO(1) }, OverloadPrefix = "K", Result = "K2" },
                new { Args = new[] { MO(c) }, OverloadPrefix = "K", Result = "K1" },
                new { Args = new[] { MO("x") }, OverloadPrefix = "K", Result = "K1" },

                // L
                new { Args = new[] { MO(sym), MO(sym) }, OverloadPrefix = "L", Result = "L1" },
                new { Args = new[] { MO("x"), MO(sym) }, OverloadPrefix = "L", Result = "L2" },
                new { Args = new[] { MO(ms), MO(sym) }, OverloadPrefix = "L", Result = "L3" },
                new { Args = new[] { MO(null), MO(sym) }, OverloadPrefix = "L", Result = "L3" },
                new { Args = new[] { MO(c), MO(sym) }, OverloadPrefix = "L", Result = "L3" },

                // M
                new { Args = new[] { MO(1) }, OverloadPrefix = "M", Result = "M1" },
                new { Args = new[] { MO(Overloads1.E.A) }, OverloadPrefix = "M", Result = "M2" },

                // N
                new { Args = new[] { MO(MutableString.CreateAscii("x")) }, OverloadPrefix = "N", Result = "N1" },
            };

            for (int i = 0; i < cases.Length; i++)
            {
                var args      = new CallArguments(Context, MO(new Overloads1()), cases[i].Args, RubyCallSignature.Simple(cases[i].Args.Length));
                var resolver  = new RubyOverloadResolver(metaBuilder, args, SelfCallConvention.SelfIsInstance, false);
                var overloads = GetInstanceMethodsStartingWith(typeof(Overloads1), cases[i].OverloadPrefix);
                var result    = resolver.ResolveOverload(i.ToString(), overloads, NarrowingLevel.None, NarrowingLevel.All);

                Assert(result.Success && result.Overload.Name == cases[i].Result);
            }
        }
Exemplo n.º 34
0
 public static RubyCallAction/*!*/ MakeShared(string/*!*/ methodName, RubyCallSignature signature) {
     // TODO: reduce usage of these sites to minimum
     return RubyMetaBinderFactory.Shared.Call(methodName, signature);
 }
Exemplo n.º 35
0
        public static MSA.DynamicExpression /*!*/ MakeCallAction(string /*!*/ name, ActionBinder /*!*/ binder, RubyCallSignature signature,
                                                                 params MSA.Expression[] /*!*/ args)
        {
            RubyCallAction call = RubyCallAction.Make(name, signature);

            switch (args.Length)
            {
            case 0: return(Ast.Dynamic(call, typeof(object), AstFactory.EmptyExpressions));

            case 1: return(Ast.Dynamic(call, typeof(object), args[0]));

            case 2: return(Ast.Dynamic(call, typeof(object), args[0], args[1]));

            case 3: return(Ast.Dynamic(call, typeof(object), args[0], args[1], args[2]));

            case 4: return(Ast.Dynamic(call, typeof(object), args[0], args[1], args[2], args[3]));

            default:
                return(Ast.Dynamic(
                           call,
                           typeof(object),
                           new ReadOnlyCollection <MSA.Expression>(args)
                           ));
            }
        }