Beispiel #1
0
 public static IDictionary <object, object> Rehash(RubyContext /*!*/ context, IDictionary <object, object> /*!*/ self)
 {
     RubyUtils.RequiresNotFrozen(context, self);
     return(ReplaceData(self, CopyKeyValuePairs(self)));
 }
Beispiel #2
0
 public static object Evaluate([NotNull] BlockParam /*!*/ block, RubyModule /*!*/ self)
 {
     return(RubyUtils.EvaluateInModule(self, block, null));
 }
Beispiel #3
0
 public static object ClassVariableSet(RubyModule /*!*/ self, [DefaultProtocol, NotNull] string /*!*/ variableName, object value)
 {
     RubyUtils.CheckClassVariableName(variableName);
     self.SetClassVariable(variableName, value);
     return(value);
 }
Beispiel #4
0
 public override DynamicMetaObject /*!*/ FallbackBinaryOperation(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/ arg, DynamicMetaObject errorSuggestion)
 {
     return(InvokeMember.FallbackInvokeMember(this, RubyUtils.MapOperator(Operation), _CallInfo, target, new[] { arg }, errorSuggestion, null));
 }
Beispiel #5
0
 public static object GetChar(string /*!*/ self, [DefaultProtocol] int index)
 {
     return(MutableStringOps.InExclusiveRangeNormalized(self.Length, ref index) ? RubyUtils.CharToObject(self[index]) : null);
 }
Beispiel #6
0
        protected override BitArray MapSpecialParameters(ParameterMapping /*!*/ mapping)
        {
            var method  = mapping.Overload;
            var infos   = method.Parameters;
            var special = new BitArray(infos.Count);

            // Method signatures                                                                                  SelfCallConvention
            // RubyMethod/RubyCtor:   [(CallSiteStorage)*, (RubyContext|RubyScope)?, (BlockParam)?, self, args]  SelfIsParameter
            // static:                [(CallSiteStorage)*, (RubyContext|RubyScope)?, (BlockParam)?, args]        NoSelf
            // instance/extension/op: [self, (CallSiteStorage)*, (RubyContext|RubyScope)?, (BlockParam)?, args]  SelfIsInstace

            var i = 0;

            if (_callConvention == SelfCallConvention.SelfIsInstance)
            {
                if (method.IsStatic)
                {
                    Debug.Assert(RubyUtils.IsOperator(method) || RubyUtils.IsExtension(method));

                    // receiver maps to the first parameter:
                    AddSimpleHiddenMapping(mapping, infos[i], true);
                    special[i++] = true;
                }
                else
                {
                    // receiver maps to the instance (no parameter info represents it):
                    mapping.AddParameter(new ParameterWrapper(null, method.DeclaringType, null, ParameterBindingFlags.ProhibitNull | ParameterBindingFlags.IsHidden));
                    mapping.AddInstanceBuilder(new InstanceBuilder(mapping.ArgIndex));
                }
            }
            else if (_callConvention == SelfCallConvention.NoSelf)
            {
                // instance methods on Object can be called with arbitrary receiver object including classes (static call):
                if (!method.IsStatic && method.DeclaringType == typeof(Object))
                {
                    // insert an InstanceBuilder that doesn't consume any arguments, only inserts the target expression as instance:
                    mapping.AddInstanceBuilder(new ImplicitInstanceBuilder());
                }
            }

            while (i < infos.Count && infos[i].ParameterType.IsSubclassOf(typeof(RubyCallSiteStorage)))
            {
                mapping.AddBuilder(new RubyCallSiteStorageBuilder(infos[i]));
                special[i++] = true;
            }

            if (i < infos.Count)
            {
                var info = infos[i];

                if (info.ParameterType == typeof(RubyScope))
                {
                    mapping.AddBuilder(new RubyScopeArgBuilder(info));
                    special[i++] = true;
                }
                else if (info.ParameterType == typeof(RubyContext))
                {
                    mapping.AddBuilder(new RubyContextArgBuilder(info));
                    special[i++] = true;
                }
                else if (method.IsConstructor && info.ParameterType == typeof(RubyClass))
                {
                    mapping.AddBuilder(new RubyClassCtorArgBuilder(info));
                    special[i++] = true;
                }
            }

            // If the method overload doesn't have a BlockParam parameter, we inject MissingBlockParam parameter and arg builder.
            // The parameter is treated as a regular explicit mandatory parameter.
            //
            // The argument builder provides no value for the actual argument expression, which makes the default binder to skip it
            // when emitting a tree for the actual method call (this is necessary since the method doesn't in fact have the parameter).
            //
            // By injecting the missing block parameter we achieve that all overloads have either BlockParam, [NotNull]BlockParam or
            // MissingBlockParam parameter. MissingBlockParam and BlockParam are convertible to each other. Default binder prefers
            // those overloads where no conversion needs to happen, which ensures the desired semantics:
            //
            //                                        conversions with desired priority (the less number the higher priority)
            // Parameters:                call w/o block      call with non-null block       call with null block
            // (implicit, MBP, ... )      MBP -> MBP (1)            BP -> MBP (3)               BP -> MBP (2)
            // (implicit, BP,  ... )      MBP -> BP  (2)            BP -> BP  (2)               BP -> BP  (1)
            // (implicit, BP!, ... )          N/A                   BP -> BP! (1)                  N/A
            //
            if (i < infos.Count && infos[i].ParameterType == typeof(BlockParam))
            {
                AddSimpleHiddenMapping(mapping, infos[i], mapping.Overload.ProhibitsNull(i));
                special[i++] = true;
            }
            else if (i >= infos.Count || infos[i].ParameterType != typeof(BlockParam))
            {
                mapping.AddBuilder(new MissingBlockArgBuilder(mapping.ArgIndex));
                mapping.AddParameter(new ParameterWrapper(null, typeof(MissingBlockParam), null, ParameterBindingFlags.IsHidden));
            }

            if (_callConvention == SelfCallConvention.SelfIsParameter)
            {
                // Ruby library methods only:
                Debug.Assert(method.IsStatic);
                Debug.Assert(i < infos.Count);

                // receiver maps to the first visible parameter:
                AddSimpleHiddenMapping(mapping, infos[i], mapping.Overload.ProhibitsNull(i));
                special[i++] = true;
            }

            return(special);
        }
Beispiel #7
0
 public static BigDecimal InducedFrom(RubyClass /*!*/ self, object value)
 {
     throw RubyExceptions.CreateTypeConversionError(RubyUtils.GetClassName(self.Context, value), self.Name);
 }
        public static MutableString Mangle(RubyClass /*!*/ self, [DefaultProtocol] string /*!*/ clrName)
        {
            var ruby = RubyUtils.TryMangleName(clrName);

            return(ruby != null?MutableString.Create(ruby, self.Context.GetIdentifierEncoding()) : null);
        }
Beispiel #9
0
 /// <summary>
 /// Check that the object responds to "succ".
 /// </summary>
 private static void CheckBegin(RubyContext /*!*/ context, object begin)
 {
     if (!RubySites.RespondTo(context, begin, "succ"))
     {
         throw RubyExceptions.CreateTypeError(String.Format("can't iterate from {0}", RubyUtils.GetClassName(context, begin)));
     }
 }
Beispiel #10
0
 public static string /*!*/ GetTerminalName(int terminal)
 {
     return(RubyUtils.TryMangleName(((Tokens)terminal).ToString()).ToUpperInvariant());
 }
Beispiel #11
0
 public static object SetDefaultValue(RubyContext /*!*/ context, Hash /*!*/ self, object value)
 {
     RubyUtils.RequiresNotFrozen(context, self);
     self.DefaultProc = null;
     return(self.DefaultValue = value);
 }
Beispiel #12
0
 public override object Execute(string code)
 {
     return(RubyUtils.Evaluate(MutableString.Create(code), _topLevelBinding.LocalScope, _topLevelBinding.LocalScope.SelfObject, null, null, 0));
 }
Beispiel #13
0
        public static object TagClass(RubyModule /*!*/ self, object tag, object clazz)
        {
            Hash tagged_classes = (Hash)GetTaggedClasses(self);

            return(RubyUtils.SetHashElement(self.Context, tagged_classes, tag, clazz));
        }
Beispiel #14
0
        internal OverloadInfo /*!*/[] /*!*/ SetMethodBasesNoLock(OverloadInfo /*!*/[] /*!*/ methods)
        {
            Debug.Assert(
                CollectionUtils.TrueForAll(methods, (method) => method.IsStatic || method.DeclaringType == typeof(Object)) ||
                CollectionUtils.TrueForAll(methods, (method) => !method.IsStatic || RubyUtils.IsExtension(method) || RubyUtils.IsOperator(method))
                );

            return(_methodBases = methods);
        }
Beispiel #15
0
        protected override DynamicMetaObjectBinder GetInteropBinder(RubyContext /*!*/ context, IList <DynamicMetaObject /*!*/> /*!*/ args,
                                                                    out MethodInfo postConverter)
        {
            postConverter = null;

            ExpressionType op;
            int            opArity = RubyUtils.TryMapOperator(_methodName, out op);

            if (opArity == 1 + args.Count)
            {
                switch (opArity)
                {
                case 1: return(context.MetaBinderFactory.InteropUnaryOperation(op));

                case 2: return(context.MetaBinderFactory.InteropBinaryOperation(op));
                }
            }

            switch (_methodName)
            {
            case "new":
                return(context.MetaBinderFactory.InteropCreateInstance(new CallInfo(args.Count)));

            case "call":
                return(context.MetaBinderFactory.InteropInvoke(new CallInfo(args.Count)));

            case "to_s":
                if (args.Count == 0)
                {
                    postConverter = Methods.ObjectToMutableString;
                    return(context.MetaBinderFactory.InteropInvokeMember("ToString", new CallInfo(0)));
                }
                goto default;

            case "to_str":
                if (args.Count == 0)
                {
                    postConverter = Methods.StringToMutableString;
                    return(context.MetaBinderFactory.InteropConvert(typeof(string), false));
                }
                goto default;

            case "[]":
                // TODO: or invoke?
                return(context.MetaBinderFactory.InteropGetIndex(new CallInfo(args.Count)));

            case "[]=":
                return(context.MetaBinderFactory.InteropSetIndex(new CallInfo(args.Count)));

            default:
                if (_methodName.LastCharacter() == '=')
                {
                    var baseName = _methodName.Substring(0, _methodName.Length - 1);
                    if (args.Count == 1)
                    {
                        return(context.MetaBinderFactory.InteropSetMember(baseName));
                    }
                    else
                    {
                        return(context.MetaBinderFactory.InteropSetIndexedProperty(baseName, new CallInfo(args.Count)));
                    }
                }
                else
                {
                    return(context.MetaBinderFactory.InteropInvokeMember(_methodName, new CallInfo(args.Count)));
                }
            }
        }
Beispiel #16
0
 public override string /*!*/ ToString()
 {
     return(RubyUtils.ObjectToMutableString(_context, this).ToString());
 }
Beispiel #17
0
 private object /*!*/ UnmarshalNewObject()
 {
     return(RubyUtils.CreateObject(ReadType()));
 }
        internal override void BuildMethodMissingCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name)
        {
            var globalScope = args.TargetClass.GlobalScope;
            var context     = globalScope.Context;

            if (name.LastCharacter() == '=')
            {
                var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 1, 1);
                if (!metaBuilder.Error)
                {
                    var scopeVar = metaBuilder.GetTemporary(typeof(Scope), "#scope");

                    metaBuilder.AddInitialization(
                        Ast.Assign(scopeVar, Methods.GetGlobalScopeFromScope.OpCall(AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope))))
                        );

                    var interopSetter = context.MetaBinderFactory.InteropSetMember(name.Substring(0, name.Length - 1));

                    metaBuilder.SetMetaResult(
                        interopSetter.Bind(
                            new DynamicMetaObject(
                                scopeVar,
                                BindingRestrictions.Empty,
                                globalScope.Scope
                                ),
                            new[] { normalizedArgs[0] }
                            ),
                        true
                        );
                }
            }
            else
            {
                RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, 0);
                Expression errorExpr = metaBuilder.Error ? Ast.Throw(metaBuilder.Result, typeof(object)) : null;

                var scopeVar             = metaBuilder.GetTemporary(typeof(Scope), "#scope");
                var scopeLookupResultVar = metaBuilder.GetTemporary(typeof(object), "#result");

                metaBuilder.AddInitialization(
                    Ast.Assign(scopeVar, Methods.GetGlobalScopeFromScope.OpCall(AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope))))
                    );

                Expression scopeLookupResultExpr = errorExpr ?? scopeLookupResultVar;
                Expression fallbackExp;

                if (name == "scope")
                {
                    fallbackExp = errorExpr ?? args.TargetExpression;
                }
                else
                {
                    // super(methodName, ...args...) - ignore argument error:
                    args.InsertMethodName(name);
                    fallbackExp = AstUtils.LightDynamic(
                        context.MetaBinderFactory.Call(Symbols.MethodMissing,
                                                       new RubyCallSignature(
                                                           args.Signature.ArgumentCount + 1,
                                                           args.Signature.Flags | RubyCallFlags.HasImplicitSelf | RubyCallFlags.IsSuperCall
                                                           )
                                                       ),
                        typeof(object),
                        args.GetCallSiteArguments(args.TargetExpression)
                        );
                }

                var scopeLookup = Ast.NotEqual(
                    Ast.Assign(scopeLookupResultVar, AstUtils.LightDynamic(context.MetaBinderFactory.InteropTryGetMemberExact(name), typeof(object), scopeVar)),
                    Expression.Constant(OperationFailed.Value)
                    );

                string unmanagled = RubyUtils.TryUnmangleMethodName(name);
                if (unmanagled != null)
                {
                    scopeLookup = Ast.OrElse(
                        scopeLookup,
                        Ast.NotEqual(
                            Ast.Assign(scopeLookupResultVar, AstUtils.LightDynamic(context.MetaBinderFactory.InteropTryGetMemberExact(unmanagled), typeof(object), scopeVar)),
                            Expression.Constant(OperationFailed.Value)
                            )
                        );
                }

                metaBuilder.Result = Ast.Condition(
                    scopeLookup,
                    scopeLookupResultExpr,
                    fallbackExp
                    );
            }
        }
Beispiel #19
0
 public override DynamicMetaObject /*!*/ FallbackUnaryOperation(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion)
 {
     return(InvokeMember.FallbackInvokeMember(this, RubyUtils.MapOperator(Operation), _CallInfo, target, DynamicMetaObject.EmptyMetaObjects, errorSuggestion));
 }
Beispiel #20
0
 public static MutableString /*!*/ Inspect(RubyContext /*!*/ context, MatchData /*!*/ self)
 {
     return(RubyUtils.ObjectToMutableString(context, self));
 }
Beispiel #21
0
 public static object SquareRoot(RubyContext /*!*/ context, BigDecimal /*!*/ self, object n)
 {
     throw RubyExceptions.CreateTypeError("wrong argument type " + RubyUtils.GetClassName(context, n) + " (expected Fixnum)");
 }
Beispiel #22
0
 private void SetupOptionsForMainFile()
 {
     LanguageSetup.Options["MainFile"]  = RubyUtils.CanonicalizePath(ConsoleOptions.FileName);
     LanguageSetup.Options["Arguments"] = PopRemainingArgs();;
 }
Beispiel #23
0
        private static void RubyThreadStart(RubyContext /*!*/ context, BlockParam /*!*/ startRoutine, object[] /*!*/ args, ThreadGroup group)
        {
            RubyThreadInfo info = RubyThreadInfo.FromThread(Thread.CurrentThread);

            info.CreatedFromRuby = true;

            info.Group = group;

            try {
                object threadResult;
                // TODO: break/returns might throw LocalJumpError if the RFC that was created for startRoutine is not active anymore:
                if (startRoutine.Yield(args, out threadResult) && startRoutine.Returning(threadResult, out threadResult))
                {
                    info.Exception = new ThreadError("return can't jump across threads");
                }
                info.Result = threadResult;
            } catch (MethodUnwinder) {
                info.Exception = new ThreadError("return can't jump across threads");
            } catch (Exception e) {
                if (info.ExitRequested)
                {
                    // Note that "e" may not be ThreadAbortException at this point If an exception was raised from a finally block,
                    // we will get that here instead
                    Utils.Log(String.Format("Thread {0} exited.", info.Thread.ManagedThreadId), "THREAD");
                    info.Result = false;
#if FEATURE_EXCEPTION_STATE
                    Thread.ResetAbort();
#endif
                }
                else
                {
                    e = RubyUtils.GetVisibleException(e);
                    RubyExceptionData.ActiveExceptionHandled(e);
                    info.Exception = e;

                    StringBuilder trace = new StringBuilder();
                    trace.Append(e.Message);
                    trace.AppendLine();
                    trace.AppendLine();
                    trace.Append(e.StackTrace);
                    trace.AppendLine();
                    trace.AppendLine();
                    RubyExceptionData data = RubyExceptionData.GetInstance(e);
                    if (data.Backtrace != null)
                    {
                        foreach (var frame in data.Backtrace)
                        {
                            trace.Append(frame.ToString());
                        }
                    }

                    Utils.Log(trace.ToString(), "THREAD");

                    if (_globalAbortOnException || info.AbortOnException)
                    {
                        throw;
                    }
                }
            } finally {
                // Its not a good idea to terminate a thread which has set Thread.critical=true, but its hard to predict
                // which thread will be scheduled next, even with green threads. However, ConditionVariable.create_timer
                // in monitor.rb explicitly does "Thread.critical=true; other_thread.raise" before exiting, and expects
                // other_thread to be scheduled immediately.
                // To deal with such code, we release the critical monitor here if the current thread is holding it
                if (context.RubyOptions.Compatibility < RubyCompatibility.Ruby19 && context.CriticalThread == Thread.CurrentThread)
                {
                    SetCritical(context, false);
                }
            }
        }
Beispiel #24
0
            internal void DoGlob(string /*!*/ baseDirectory, int position, bool isPreviousDoubleStar)
            {
                if (!_pal.DirectoryExists(baseDirectory))
                {
                    return;
                }

                bool   containsWildcard;
                int    patternEnd        = FindNextSeparator(position, true, out containsWildcard);
                bool   isLastPathSegment = (patternEnd == _pattern.Length);
                string dirSegment        = _pattern.Substring(position, patternEnd - position);

                if (!isLastPathSegment)
                {
                    patternEnd++;
                }

                if (!containsWildcard)
                {
                    string path = baseDirectory + "/" + dirSegment;
                    TestPath(path, patternEnd, isLastPathSegment);
                    return;
                }

                bool doubleStar = dirSegment.Equals("**");

                if (doubleStar && !isPreviousDoubleStar)
                {
                    DoGlob(baseDirectory, patternEnd, true);
                }

                foreach (string file in _pal.GetFileSystemEntries(baseDirectory, "*"))
                {
                    string objectName = Path.GetFileName(file);
                    if (FnMatch(dirSegment, objectName, _flags))
                    {
                        var canon = RubyUtils.CanonicalizePath(file);
                        TestPath(canon, patternEnd, isLastPathSegment);
                        if (doubleStar)
                        {
                            DoGlob(canon, position, true);
                        }
                    }
                }
                if (isLastPathSegment && (_flags & Constants.FNM_DOTMATCH) != 0 || dirSegment[0] == '.')
                {
                    if (FnMatch(dirSegment, ".", _flags))
                    {
                        string directory = baseDirectory + "/.";
                        if (_dirOnly)
                        {
                            directory += '/';
                        }
                        TestPath(directory, patternEnd, true);
                    }
                    if (FnMatch(dirSegment, "..", _flags))
                    {
                        string directory = baseDirectory + "/..";
                        if (_dirOnly)
                        {
                            directory += '/';
                        }
                        TestPath(directory, patternEnd, true);
                    }
                }
            }
Beispiel #25
0
        internal static RubyArray /*!*/ GetMethods(RubyModule /*!*/ self, bool inherited, RubyMethodAttributes attributes,
                                                   IEnumerable <string> foreignMembers)
        {
            var result = new RubyArray();

            using (self.Context.ClassHierarchyLocker()) {
                self.ForEachMember(inherited, attributes, foreignMembers, (name, module, member) => {
                    if (member.IsInteropMember && (module.Restrictions & ModuleRestrictions.NoNameMapping) == 0 && RubyUtils.HasMangledName(name))
                    {
                        if (Tokenizer.IsMethodName(name) || Tokenizer.IsOperatorName(name))
                        {
                            result.Add(new ClrName(name));
                        }
                    }
                    else
                    {
                        result.Add(self.Context.StringifyIdentifier(name));
                    }
                });
            }
            return(result);
        }
 protected override bool HasIdentity(object data)
 {
     return(RubyUtils.IsRubyValueType(data) || base.HasIdentity(data));
 }
Beispiel #27
0
 public static object Execute([NotNull] BlockParam /*!*/ block, RubyModule /*!*/ self, params object[] /*!*/ args)
 {
     return(RubyUtils.EvaluateInModule(self, block, args));
 }
Beispiel #28
0
 // overridden to set the default encoding to -KX
 protected override int RunFile(string fileName)
 {
     return(RunFile(Engine.CreateScriptSourceFromFile(RubyUtils.CanonicalizePath(fileName), GetSourceCodeEncoding())));
 }
Beispiel #29
0
 public static object GetConstantValue(RubyScope /*!*/ scope, RubyModule /*!*/ self, [DefaultProtocol, NotNull] string /*!*/ constantName)
 {
     return(RubyUtils.GetConstant(scope.GlobalScope, self, constantName, true));
 }
Beispiel #30
0
 public static IDictionary <object, object> Clear(RubyContext /*!*/ context, IDictionary <object, object> /*!*/ self)
 {
     RubyUtils.RequiresNotFrozen(context, self);
     self.Clear();
     return(self);
 }