Beispiel #1
1
 public static object Load(RubyScope/*!*/ scope, RubyModule/*!*/ self, MutableString/*!*/ libraryName)
 {
     object loaded;
     scope.RubyContext.Loader.LoadFile(null, self, libraryName, LoadFlags.ResolveLoaded | LoadFlags.AnyLanguage, out loaded);
     Debug.Assert(loaded != null);
     return loaded;
 }
 public static object MethodRetry(RubyScope/*!*/ scope, Proc proc) {
     if (proc != null) {
         return RetrySingleton;
     } else {
         throw new LocalJumpError("retry used out of rescue", scope.FlowControlScope);
     }
 }
Beispiel #3
0
 internal Proc(ProcKind kind, object self, RubyScope/*!*/ scope, BlockDispatcher/*!*/ dispatcher) {
     Assert.NotNull(scope, dispatcher);
     _kind = kind;
     _self = self;
     _scope = scope;
     _dispatcher = dispatcher;
 }
Beispiel #4
0
        public virtual Proc/*!*/ ToProc(RubyScope/*!*/ scope) {
            ContractUtils.RequiresNotNull(scope, "scope");

            // TODO: 
            // This should pass a proc parameter (use BlockDispatcherUnsplatProcN).
            // MRI 1.9.2 doesn't do so though (see http://redmine.ruby-lang.org/issues/show/3792).

            if (_procDispatcher == null) {
                var site = CallSite<Func<CallSite, object, object, object>>.Create(
                    // TODO: use InvokeBinder
                    RubyCallAction.Make(
                        scope.RubyContext, "call",
                        new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.HasSplattedArgument)
                    )
                );

                var block = new BlockCallTargetUnsplatN((blockParam, self, args, unsplat) => {
                    // block takes no parameters but unsplat => all actual arguments are added to unsplat:
                    Debug.Assert(args.Length == 0);

                    return site.Target(site, this, unsplat);
                });

                _procDispatcher = new BlockDispatcherUnsplatN(0, 
                    BlockDispatcher.MakeAttributes(BlockSignatureAttributes.HasUnsplatParameter, _info.GetArity()),
                    null, 0
                );

                _procDispatcher.SetMethod(block);
            }

            // TODO: 
            // MRI: source file/line are that of the to_proc method call:
            return new Proc(ProcKind.Block, scope.SelfObject, scope, _procDispatcher);
        }
Beispiel #5
0
 /// <summary>
 /// Builds backtrace for the exception if it wasn't built yet. 
 /// Captures a full stack trace starting with the current frame and combines it with the trace of the exception.
 /// Called from compiled code.
 /// </summary>
 internal void CaptureExceptionTrace(RubyScope/*!*/ scope) {
     if (_backtrace == null) {
         StackTrace catchSiteTrace = RubyStackTraceBuilder.ExceptionDebugInfoAvailable ? new StackTrace(true) : new StackTrace();
         _backtrace = new RubyStackTraceBuilder(scope.RubyContext, _exception, catchSiteTrace, scope.InterpretedFrame != null).RubyTrace;
         DynamicSetBacktrace(scope.RubyContext, _backtrace);
     }
 }
            public DebugView(RubyScope /*!*/ scope)
            {
                Assert.NotNull(scope);
                _scope = scope;
                var name = _scope.RubyContext.GetImmediateClassOf(_scope._selfObject).GetDisplayName(_scope.RubyContext, true);

                _selfClassName = name != null?name.ConvertToString() : null;
            }
Beispiel #7
0
 private static RubyModule GetModule(RubyScope scope, String className)
 {
     RubyModule module;
     if (!scope.RubyContext.TryGetModule(scope.GlobalScope, className, out module)) {
         throw RubyExceptions.CreateNameError(className);
     }
     return module;
 }
Beispiel #8
0
 /// <summary>
 /// Builds backtrace for the exception if it wasn't built yet.
 /// Captures a full stack trace starting with the current frame and combines it with the trace of the exception.
 /// Called from compiled code.
 /// </summary>
 internal void CaptureExceptionTrace(RubyScope /*!*/ scope)
 {
     if (_backtrace == null)
     {
         StackTrace catchSiteTrace = RubyStackTraceBuilder.GetClrStackTrace(null);
         _backtrace = new RubyStackTraceBuilder(scope.RubyContext, _exception, catchSiteTrace, scope.InterpretedFrame != null).RubyTrace;
         DynamicSetBacktrace(scope.RubyContext, _backtrace);
     }
 }
Beispiel #9
0
 public static bool IsMethodUnwinderTargetFrame(RubyScope/*!*/ scope, Exception/*!*/ exception) {
     var unwinder = exception as MethodUnwinder;
     if (unwinder == null) {
         RubyExceptionData.GetInstance(exception).CaptureExceptionTrace(scope);
         return false;
     } else {
         return unwinder.TargetFrame == scope.RuntimeFlowControl;
     }
 }
Beispiel #10
0
        public RubyMethodScope GetInnerMostMethodScope()
        {
            RubyScope scope = this;

            while (scope != null && scope.Kind != ScopeKind.Method)
            {
                scope = scope.Parent;
            }
            return((RubyMethodScope)scope);
        }
Beispiel #11
0
        public static object/*!*/ Require(RubyScope/*!*/ scope, RubyModule/*!*/ self, MutableString/*!*/ libraryName) {
            object loaded;
            
            scope.RubyContext.Loader.LoadFile(
                null, self, libraryName, LoadFlags.LoadOnce | LoadFlags.AppendExtensions | LoadFlags.ResolveLoaded, out loaded
            );

            Debug.Assert(loaded != null);
            return loaded;
        }
Beispiel #12
0
        public static RubyModuleScope/*!*/ CreateModuleScope(LocalsDictionary/*!*/ locals, RubyScope/*!*/ parent,
            RuntimeFlowControl/*!*/ rfc, RubyModule/*!*/ module) {
            Assert.NotNull(locals, parent, rfc, module);

            RubyModuleScope scope = new RubyModuleScope(parent, module, false, rfc, module);
            scope.SetDebugName((module.IsClass ? "class" : "module") + " " + module.Name);

            scope.Frame = locals;
            return scope;
        }
Beispiel #13
0
 public static object MethodRetry(RubyScope/*!*/ scope, Proc proc) {
     if (proc != null) {
         return BlockReturnResult.Retry;
     } else {
         // TODO: can this happen? 
         // If proc was null then the block argument passed to the call-with-block that returned RetrySingleton would be null and thus 
         // the call cannot yield to any block that retries.
         throw new LocalJumpError("retry used out of rescue", scope.FlowControlScope);
     }
 }
Beispiel #14
0
        public RubyClosureScope /*!*/ GetInnerMostClosureScope()
        {
            RubyScope scope = this;

            while (scope != null && !scope.IsClosureScope)
            {
                scope = scope.Parent;
            }
            return((RubyClosureScope)scope);
        }
Beispiel #15
0
        // thread-safe:
        // Returns null on success, the lexically inner-most module on failure.
        internal RubyModule TryResolveConstantNoLock(RubyGlobalScope autoloadScope, string /*!*/ name, out ConstantStorage result)
        {
            var context = RubyContext;

            context.RequiresClassHierarchyLock();

            RubyScope scope = this;

            // lexical lookup first:
            RubyModule innerMostModule = null;

            do
            {
                RubyModule module = scope.Module;

                if (module != null)
                {
                    Debug.Assert(module.Context == context);

                    if (module.TryGetConstantNoLock(autoloadScope, name, out result))
                    {
                        return(null);
                    }

                    // remember the module:
                    if (innerMostModule == null)
                    {
                        innerMostModule = module;
                    }
                }

                scope = scope.Parent;
            } while (scope != null);

            // check the inner most module and it's base classes/mixins:
            if (innerMostModule != null)
            {
                if (innerMostModule.TryResolveConstantNoLock(autoloadScope, name, out result))
                {
                    return(null);
                }
            }
            else
            {
                innerMostModule = context.ObjectClass;
            }

            if (context.ObjectClass.TryResolveConstantNoLock(autoloadScope, name, out result))
            {
                return(null);
            }

            return(innerMostModule);
        }
Beispiel #16
0
        public void InitializeLibrary(RubyScope scope)
        {
            KernelOps.Require(scope, this, MutableString.CreateAscii("json/common"));

            _maxNesting = scope.RubyContext.CreateAsciiSymbol("max_nesting");
            _allowNan = scope.RubyContext.CreateAsciiSymbol("allow_nan");
            _jsonCreatable = scope.RubyContext.CreateAsciiSymbol("json_creatable?");
            _jsonCreate = scope.RubyContext.CreateAsciiSymbol("json_create");
            _createId = scope.RubyContext.CreateAsciiSymbol("create_id");
            _createAdditions = scope.RubyContext.CreateAsciiSymbol("create_additions");
            _chr = scope.RubyContext.CreateAsciiSymbol("chr");
        }
Beispiel #17
0
 private static RubyCompilerOptions /*!*/ CreateCompilerOptionsForEval(RubyScope /*!*/ targetScope, RubyMethodScope methodScope,
                                                                       bool isModuleEval, int line)
 {
     return(new RubyCompilerOptions(targetScope.RubyContext.RubyOptions)
     {
         IsEval = true,
         IsModuleEval = isModuleEval,
         LocalNames = targetScope.GetVisibleLocalNames(),
         TopLevelMethodName = (methodScope != null) ? methodScope.Method.DefinitionName : null,
         InitialLocation = new SourceLocation(0, line <= 0 ? 1 : line, 1),
     });
 }
Beispiel #18
0
        public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, 
            RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]RubyRegex pattern)
        {
            object blockResult;
            MutableString result;
            self.TrackChanges();
            object r = BlockReplaceAll(tosConversion, scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone());

            RequireNoVersionChange(self);
            return r;
        }
Beispiel #19
0
        public static void SetDataConstant(RubyScope/*!*/ scope, string/*!*/ dataPath, int dataOffset) {
            Debug.Assert(dataOffset >= 0);
            RubyFile dataFile;
            RubyContext context = scope.RubyContext;
            if (context.DomainManager.Platform.FileExists(dataPath)) {
                dataFile = new RubyFile(context, dataPath, RubyFileMode.RDONLY);
                dataFile.Seek(dataOffset, SeekOrigin.Begin);
            } else {
                dataFile = null;
            }

            context.ObjectClass.SetConstant("DATA", dataFile);
        }
Beispiel #20
0
        public ParserEngineState(Parser parser, RubyScope scope, MutableString source)
        {
            Parser = parser;
            Scope = scope;
            OriginalSource = source;
            Source = source.ConvertToString();

            CreateID = Helpers.GetCreateId(scope);
            AllowNaN = DEFAULT_ALLOW_NAN;
            MaxNesting = DEFAULT_MAX_NESTING;
            CurrentNesting = 0;
            Memo = 0;
        }
Beispiel #21
0
        /// <summary>
        /// Builds backtrace for the exception if it wasn't built yet.
        /// Captures a full stack trace starting with the current frame and combines it with the trace of the exception.
        /// Called from compiled code.
        /// </summary>
        internal void CaptureExceptionTrace(RubyScope /*!*/ scope)
        {
            if (_backtrace == null)
            {
#if FEATURE_STACK_TRACE
                StackTrace catchSiteTrace = RubyStackTraceBuilder.GetClrStackTrace(null);
                _backtrace = new RubyStackTraceBuilder(scope.RubyContext, _exception, catchSiteTrace, scope.InterpretedFrame != null).RubyTrace;
#else
                _backtrace = new RubyArray();
#endif
                DynamicSetBacktrace(scope.RubyContext, _backtrace);
            }
        }
 public static object MethodRetry(RubyScope /*!*/ scope, Proc proc)
 {
     if (proc != null)
     {
         return(BlockReturnResult.Retry);
     }
     else
     {
         // TODO: can this happen?
         // If proc was null then the block argument passed to the call-with-block that returned RetrySingleton would be null and thus
         // the call cannot yield to any block that retries.
         throw new LocalJumpError("retry used out of rescue", scope.FlowControlScope);
     }
 }
Beispiel #23
0
        public Parser(RubyScope scope, MutableString source, Hash options)
        {
            InitializeLibrary(scope);

            _json = new ParserEngineState(this, scope, source);
            if (options.Count > 0) {
                if (options.ContainsKey(_maxNesting)) {
                    _json.MaxNesting = options[_maxNesting] is int ? (int)options[_maxNesting] : 0;
                }
                _json.AllowNaN = options.ContainsKey(_allowNan) ? (bool)options[_allowNan] : ParserEngineState.DEFAULT_ALLOW_NAN;
                // TODO: check needed, create_id could be TrueClass, FalseClass, NilClass or String
                _json.CreateID = options.ContainsKey(_createAdditions) && (bool)options[_createAdditions] ? Helpers.GetCreateId(scope) : null;
            }
        }
Beispiel #24
0
        private static RubyModule/*!*/ SetVisibility(RubyScope/*!*/ scope, object/*!*/ self, string/*!*/[]/*!*/ methodNames, RubyMethodAttributes attributes) {
            Assert.NotNull(scope, self, methodNames);
            RubyModule module;

            // MRI: Method is searched in the class of self (Object), not in the main singleton class.
            // IronRuby specific: If we are in a top-level scope with redirected method lookup module we use that module (hosted scopes).
            var topScope = scope.Top.GlobalScope.TopLocalScope;
            if (scope == topScope && topScope.MethodLookupModule != null) {
                module = topScope.MethodLookupModule;
            } else {
                module = scope.RubyContext.GetClassOf(self);
            }
            ModuleOps.SetMethodAttributes(scope, module, methodNames, attributes);
            return module;
        }
Beispiel #25
0
        private RubyModule /*!*/ GetInnerMostModule(bool skipSingletons, RubyModule /*!*/ fallbackModule)
        {
            RubyScope scope = this;

            do
            {
                RubyModule result = scope.Module;
                if (result != null && (!skipSingletons || !result.IsSingletonClass))
                {
                    return(result);
                }
                scope = scope.Parent;
            } while (scope != null);
            return(fallbackModule);
        }
Beispiel #26
0
        public RubyModule /*!*/ GetInnerMostModule(bool skipSingletons)
        {
            RubyScope scope = this;

            do
            {
                RubyModule result = scope.Module;
                if (result != null && (!skipSingletons || !result.IsSingletonClass))
                {
                    return(result);
                }
                scope = (RubyScope)scope.Parent;
            } while (scope != null);
            return(RubyContext.ObjectClass);
        }
 public static object MethodPropagateReturn(RubyScope /*!*/ scope, Proc block, BlockReturnResult /*!*/ unwinder)
 {
     if (unwinder.TargetFrame == scope)
     {
         return(unwinder.ReturnValue);
     }
     else if (block != null)
     {
         return(unwinder);
     }
     else
     {
         throw unwinder.ToUnwinder();
     }
 }
Beispiel #28
0
        public static Hash ToJsonRawObject(RubyScope scope, MutableString self)
        {
            byte[] selfBuffer = self.ToByteArray();
            var array = new RubyArray(selfBuffer.Length);
            foreach (byte b in selfBuffer) {
                array.Add(b & 0xFF);
            }

            var context = scope.RubyContext;
            var result = new Hash(context);
            var createId = Helpers.GetCreateId(scope);

            result.Add(createId, MutableString.Create(context.GetClassName(self), RubyEncoding.Binary));
            result.Add(MutableString.CreateAscii("raw"), array);
            return result;
        }
Beispiel #29
0
        internal RubyModule /*!*/ GetMethodDefinitionOwner()
        {
            // MRI 1.9:
            // - define_method doesn't influence the definition owner (unlike MRI 1.8)
            // - skips module_eval blocks above method scope
            // MRI 1.8:
            // - skips module_eval and define_method blocks above method scope.
            // IronRuby:
            // - Fallback to the top-level singleton class when hosted.

            RubyScope scope = this;

            while (true)
            {
                Debug.Assert(scope != null);

                switch (scope.Kind)
                {
                case ScopeKind.TopLevel:
                    Debug.Assert(scope == Top);
                    return(Top.MethodLookupModule ?? Top.TopModuleOrObject);

                case ScopeKind.Module:
                    Debug.Assert(scope.Module != null);
                    return(scope.Module);

                case ScopeKind.Method:
                    return(scope.GetInnerMostModuleForMethodLookup());

                case ScopeKind.BlockMethod:
                    if (RubyContext.RubyOptions.Compatibility == RubyCompatibility.Ruby19)
                    {
                        break;
                    }
                    return(((RubyBlockScope)scope).BlockFlowControl.Proc.Method.DeclaringModule);

                case ScopeKind.BlockModule:
                    BlockParam blockParam = ((RubyBlockScope)scope).BlockFlowControl;
                    Debug.Assert(blockParam.MethodLookupModule != null);
                    return(blockParam.MethodLookupModule);
                }

                scope = scope.Parent;
            }
        }
        private static void EvalNextOrRedo(RubyScope /*!*/ scope, object returnValue, bool isRedo)
        {
            if (scope.InLoop)
            {
                throw new BlockUnwinder(returnValue, isRedo);
            }

            RubyBlockScope  blockScope;
            RubyMethodScope methodScope;

            scope.GetInnerMostBlockOrMethodScope(out blockScope, out methodScope);
            if (blockScope != null)
            {
                throw new BlockUnwinder(returnValue, isRedo);
            }

            throw new LocalJumpError(String.Format("unexpected {0}", isRedo ? "redo" : "next"));
        }
Beispiel #31
0
        public RubyScope /*!*/ GetMethodAttributesDefinitionScope()
        {
            RubyScope scope = this;

            while (true)
            {
                switch (scope.Kind)
                {
                case ScopeKind.Module:
                case ScopeKind.BlockModule:
                case ScopeKind.Method:
                case ScopeKind.TopLevel:
                case ScopeKind.FileInitializer:
                    return(scope);
                }

                scope = scope.Parent;
            }
        }
Beispiel #32
0
        internal object ResolveLocalVariable(string /*!*/ name)
        {
            RubyScope scope = this;

            while (true)
            {
                object result;
                if (scope.Frame.TryGetValue(SymbolTable.StringToId(name), out result))
                {
                    return(result);
                }

                if (!scope.InheritsLocalVariables)
                {
                    return(null);
                }

                scope = (RubyScope)scope.Parent;
            }
        }
Beispiel #33
0
        internal object ResolveAndSetLocalVariable(string /*!*/ name, object value)
        {
            RubyScope scope = this;

            while (true)
            {
                if (scope.TrySetLocal(name, value))
                {
                    return(value);
                }

                if (!scope.InheritsLocalVariables)
                {
                    DefineDynamicVariable(name, value);
                    return(value);
                }

                scope = scope.Parent;
            }
        }
Beispiel #34
0
        internal object ResolveLocalVariable(string /*!*/ name)
        {
            RubyScope scope = this;

            while (true)
            {
                object value;
                if (scope.TryGetLocal(name, out value))
                {
                    return(value);
                }

                if (!scope.InheritsLocalVariables)
                {
                    return(null);
                }

                scope = scope.Parent;
            }
        }
Beispiel #35
0
        public List <string /*!*/> /*!*/ GetVisibleLocalNames()
        {
            var       result = new List <string>();
            RubyScope scope  = this;

            while (true)
            {
                foreach (string name in scope.GetDeclaredLocalSymbols())
                {
                    result.Add(name);
                }

                if (!scope.InheritsLocalVariables)
                {
                    return(result);
                }

                scope = scope.Parent;
            }
        }
        public static void EvalRetry(RubyScope/*!*/ scope) {
            if (scope.InRescue) {
                throw new EvalUnwinder(BlockReturnReason.Retry, RetrySingleton);
            }

            RubyBlockScope blockScope;
            RubyMethodScope methodScope;
            scope.GetInnerMostBlockOrMethodScope(out blockScope, out methodScope);

            if (methodScope != null && methodScope.BlockParameter != null) {
                throw new EvalUnwinder(BlockReturnReason.Retry, RetrySingleton);
            } else if (blockScope != null) {
                if (blockScope.BlockFlowControl.CallerKind == BlockCallerKind.Yield) {
                    throw new EvalUnwinder(BlockReturnReason.Retry, null, blockScope.BlockFlowControl.Proc.Kind, RetrySingleton);
                }
                //if (blockScope.BlockFlowControl.IsMethod) {
                throw new LocalJumpError("retry from proc-closure");// TODO: RFC
            }

            throw new LocalJumpError("retry used out of rescue", scope.FlowControlScope);
        }
        public static void EvalBreak(RubyScope /*!*/ scope, object returnValue)
        {
            if (scope.InLoop)
            {
                throw new EvalUnwinder(BlockReturnReason.Break, returnValue);
            }

            RubyBlockScope  blockScope;
            RubyMethodScope methodScope;

            scope.GetInnerMostBlockOrMethodScope(out blockScope, out methodScope);
            if (blockScope != null)
            {
                var proc = blockScope.BlockFlowControl.Proc;
                throw new EvalUnwinder(BlockReturnReason.Break, proc.Converter, proc.Kind, returnValue);
            }
            else
            {
                throw new LocalJumpError("unexpected break");
            }
        }
Beispiel #38
0
        public static object GetConstant(RubyScope /*!*/ scope, RubyModule /*!*/ owner, string /*!*/ name, bool lookupObject)
        {
            Assert.NotNull(scope, owner, name);

            object result;

            if (owner.TryResolveConstant(scope.GlobalScope, name, out result))
            {
                return(result);
            }

            RubyClass objectClass = owner.Context.ObjectClass;

            if (owner != objectClass && lookupObject && objectClass.TryResolveConstant(scope.GlobalScope, name, out result))
            {
                return(result);
            }

            CheckConstantName(name);
            return(RubySites.ModuleConstMissing(scope.RubyContext, owner, name));
        }
Beispiel #39
0
        public RubyScope /*!*/ GetMethodAttributesDefinitionScope()
        {
            RubyScope scope = this;

            while (true)
            {
                if (scope.Kind == ScopeKind.Block)
                {
                    BlockParam blockParam = ((RubyBlockScope)scope).BlockParameter;
                    if (blockParam.ModuleDeclaration != null && blockParam.SuperMethodName == null)
                    {
                        return(scope);
                    }
                }
                else
                {
                    return(scope);
                }

                scope = (RubyScope)scope.Parent;
            }
        }
Beispiel #40
0
        internal RubyModule /*!*/ GetMethodDefinitionOwner()
        {
            RubyScope scope      = this;
            bool      skipBlocks = false;

            while (true)
            {
                Debug.Assert(scope != null);

                switch (scope.Kind)
                {
                case ScopeKind.TopLevel:
                    return(((RubyTopLevelScope)scope).TopModuleOrObject);

                case ScopeKind.Module:
                    Debug.Assert(scope.Module != null);
                    return(scope.Module);

                case ScopeKind.Method:
                    // MRI 1.8: skips module_evals above
                    // MRI 1.9: just continue search for a module or module_eval
                    skipBlocks = RubyContext.RubyOptions.Compatibility == RubyCompatibility.Ruby18;
                    break;

                case ScopeKind.Block:
                    if (!skipBlocks)
                    {
                        BlockParam blockParam = ((RubyBlockScope)scope).BlockParameter;
                        if (blockParam.ModuleDeclaration != null)
                        {
                            return(blockParam.ModuleDeclaration);
                        }
                    }
                    break;
                }

                scope = (RubyScope)scope.Parent;
            }
        }
        public static bool BlockYield(RubyScope /*!*/ scope, BlockParam /*!*/ ownerBlockFlowControl, BlockParam /*!*/ yieldedBlockFlowControl, object returnValue)
        {
            Assert.NotNull(scope, ownerBlockFlowControl, yieldedBlockFlowControl);

            switch (yieldedBlockFlowControl.ReturnReason)
            {
            case BlockReturnReason.Retry:
                // the result that the caller returns should already be RetrySingleton:
                BlockRetry(ownerBlockFlowControl);
                return(true);

            case BlockReturnReason.Return:
                // the result that the caller returns should already be MethodUnwinder:
                YieldBlockReturn(ownerBlockFlowControl, returnValue);
                return(true);

            case BlockReturnReason.Break:
                YieldBlockBreak(scope, ownerBlockFlowControl, yieldedBlockFlowControl, returnValue);
                return(true);
            }
            return(false);
        }
        public static bool EvalYield(RubyScope /*!*/ scope, BlockParam /*!*/ yieldedBlockFlowControl, object returnValue)
        {
            Assert.NotNull(scope, yieldedBlockFlowControl);

            switch (yieldedBlockFlowControl.ReturnReason)
            {
            case BlockReturnReason.Retry:
                // the result that the caller returns is already RetrySingleton:
                Debug.Assert(returnValue == BlockReturnResult.Retry);
                EvalRetry(scope);
                throw Assert.Unreachable;

            case BlockReturnReason.Return:
                // The result that the caller returns is already MethodUnwinder.
                // We can't continue fast unwind since the eval call-site doesn't propagate it (a call w/o block).
                throw ((BlockReturnResult)returnValue).ToUnwinder();

            case BlockReturnReason.Break:
                YieldEvalBreak(yieldedBlockFlowControl, returnValue);
                throw Assert.Unreachable;
            }
            return(false);
        }
Beispiel #43
0
        public bool TryResolveConstant(bool autoload, string /*!*/ name, out object result)
        {
            Scope     autoloadScope = autoload ? GlobalScope : null;
            RubyScope scope         = this;

            // lexical lookup first:
            RubyModule innerMostModule = null;

            do
            {
                RubyModule module = scope.Module;

                if (module != null)
                {
                    if (module.TryGetConstant(autoloadScope, name, out result))
                    {
                        return(true);
                    }

                    // remember the module:
                    if (innerMostModule == null)
                    {
                        innerMostModule = module;
                    }
                }

                scope = (RubyScope)scope.Parent;
            } while (scope != null);

            // check the inner most module and it's base classes/mixins:
            if (innerMostModule != null && innerMostModule.TryResolveConstant(autoloadScope, name, out result))
            {
                return(true);
            }

            return(RubyContext.ObjectClass.TryResolveConstant(autoloadScope, name, out result));
        }
Beispiel #44
0
        /// <summary>
        /// Returns
        /// -1 if there is no method or block-method scope,
        /// 0 if the target scope is a method scope,
        /// id > 0 of the target lambda for block-method scopes.
        /// </summary>
        internal int GetSuperCallTarget(out RubyModule declaringModule, out string /*!*/ methodName, out RubyScope targetScope)
        {
            RubyScope scope = this;

            while (true)
            {
                Debug.Assert(scope != null);

                switch (scope.Kind)
                {
                case ScopeKind.Method:
                    RubyMethodScope methodScope = (RubyMethodScope)scope;
                    // See RubyOps.DefineMethod for why we can use Method here.
                    declaringModule = methodScope.DeclaringModule;
                    methodName      = methodScope.DefinitionName;
                    targetScope     = scope;
                    return(0);

                case ScopeKind.BlockMethod:
                    RubyLambdaMethodInfo info = ((RubyBlockScope)scope).BlockFlowControl.Proc.Method;
                    Debug.Assert(info != null);
                    declaringModule = info.DeclaringModule;
                    methodName      = info.DefinitionName;
                    targetScope     = scope;
                    return(info.Id);

                case ScopeKind.TopLevel:
                    declaringModule = null;
                    methodName      = null;
                    targetScope     = null;
                    return(-1);
                }

                scope = scope.Parent;
            }
        }
Beispiel #45
0
        // TODO:
        public List <string /*!*/> /*!*/ GetVisibleLocalNames()
        {
            var       result = new List <string>();
            RubyScope scope  = this;

            while (true)
            {
                foreach (object name in scope.Frame.Keys)
                {
                    string strName = name as string;
                    if (strName != null && !strName.StartsWith("#"))
                    {
                        result.Add(strName);
                    }
                }

                if (!scope.InheritsLocalVariables)
                {
                    return(result);
                }

                scope = (RubyScope)scope.Parent;
            }
        }
Beispiel #46
0
        internal void GetSuperCallTarget(out RubyModule declaringModule, out string /*!*/ methodName, out object self)
        {
            RubyScope scope = this;

            while (true)
            {
                Debug.Assert(scope != null);

                switch (scope.Kind)
                {
                case ScopeKind.Method:
                    RubyMethodScope methodScope = (RubyMethodScope)scope;
                    // See RubyOps.DefineMethod for why we can use Method here.
                    declaringModule = methodScope.Method.DeclaringModule;
                    methodName      = methodScope.Method.DefinitionName;
                    self            = scope.SelfObject;
                    return;

                case ScopeKind.Block:
                    BlockParam blockParam = ((RubyBlockScope)scope).BlockParameter;
                    if (blockParam.SuperMethodName != null)
                    {
                        declaringModule = blockParam.ModuleDeclaration;
                        methodName      = blockParam.SuperMethodName;
                        self            = scope.SelfObject;
                        return;
                    }
                    break;

                case ScopeKind.TopLevel:
                    throw RubyOps.MakeTopLevelSuperException();
                }

                scope = (RubyScope)scope.Parent;
            }
        }
Beispiel #47
0
        public void GetInnerMostBlockOrMethodScope(out RubyBlockScope blockScope, out RubyMethodScope methodScope)
        {
            methodScope = null;
            blockScope  = null;
            RubyScope scope = this;

            while (scope != null)
            {
                switch (scope.Kind)
                {
                case ScopeKind.Block:
                case ScopeKind.BlockMethod:
                case ScopeKind.BlockModule:
                    blockScope = (RubyBlockScope)scope;
                    return;

                case ScopeKind.Method:
                    methodScope = (RubyMethodScope)scope;
                    return;
                }

                scope = scope.Parent;
            }
        }
Beispiel #48
0
 public static MutableString/*!*/ ReadLine(RubyScope/*!*/ scope, RubyIO/*!*/ self, [DefaultProtocol, NotNull]Union<MutableString, int> separatorOrLimit) {
     if (separatorOrLimit.IsFixnum()) {
         return ReadLine(scope, self, scope.RubyContext.InputSeparator, separatorOrLimit.Fixnum());
     } else {
         return ReadLine(scope, self, separatorOrLimit.String(), -1);
     }
 }
Beispiel #49
0
 public static MutableString/*!*/ ReadLine(RubyScope/*!*/ scope, RubyIO/*!*/ self, DynamicNull separator) {
     return ReadLine(scope, self, null, -1);
 }
Beispiel #50
0
 public static MutableString/*!*/ ReadLine(RubyScope/*!*/ scope, RubyIO/*!*/ self) {
     return ReadLine(scope, self, scope.RubyContext.InputSeparator, -1);
 }
Beispiel #51
0
        public static MutableString Gets(RubyScope/*!*/ scope, RubyIO/*!*/ self, [DefaultProtocol]MutableString separator, [DefaultProtocol]int limit) {

            MutableString result = self.ReadLineOrParagraph(separator, limit);
            if (result != null) {
                result.IsTainted = true;
            }

            scope.GetInnerMostClosureScope().LastInputLine = result;
            scope.RubyContext.InputProvider.LastInputLineNumber = ++self.LineNumber;

            return result;
        }
Beispiel #52
0
 public static MutableString Gets(RubyScope/*!*/ scope, RubyIO/*!*/ self, DynamicNull separator) {
     return Gets(scope, self, null, -1);
 }
        public override void SetValue(RubyContext/*!*/ context, RubyScope scope, string/*!*/ name, object value) {
            switch (_id) {
                // regex:
                case GlobalVariableId.MatchData:
                    if (scope == null) {
                        throw ReadOnlyError(name);
                    }

                    scope.GetInnerMostClosureScope().CurrentMatch = (value != null) ? RequireType<MatchData>(value, name, "MatchData") : null;
                    return;

                case GlobalVariableId.MatchLastGroup:
                case GlobalVariableId.MatchPrefix:
                case GlobalVariableId.MatchSuffix:
                case GlobalVariableId.EntireMatch:
                    throw ReadOnlyError(name);
                
                
                // exceptions:
                case GlobalVariableId.CurrentException:
                    context.SetCurrentException(value);
                    return;

                case GlobalVariableId.CurrentExceptionBacktrace:
                    context.SetCurrentExceptionBacktrace(value);
                    return;


                // input:
                case GlobalVariableId.LastInputLine:
                    if (scope == null) {
                        throw ReadOnlyError(name);
                    }
                    scope.GetInnerMostClosureScope().LastInputLine = value;
                    return;

                case GlobalVariableId.LastInputLineNumber:
                    context.InputProvider.LastInputLineNumber = RequireType<int>(value, name, "Fixnum");
                    return;

                case GlobalVariableId.CommandLineArguments:
                case GlobalVariableId.InputFileName:
                    throw ReadOnlyError(name);

                // output:
                case GlobalVariableId.OutputStream:
                    context.StandardOutput = RequireWriteProtocol(context, value, name);
                    return;

                case GlobalVariableId.ErrorOutputStream:
                    context.StandardErrorOutput = RequireWriteProtocol(context, value, name);
                    break;

                case GlobalVariableId.InputStream:
                    context.StandardInput = value;
                    return;

                // separators:
                case GlobalVariableId.InputContent:
                    throw ReadOnlyError(name);

                case GlobalVariableId.InputSeparator:
                    context.InputSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
                    return;

                case GlobalVariableId.OutputSeparator:
                    context.OutputSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
                    return;

                case GlobalVariableId.StringSeparator:
                    // type not enforced:
                    context.StringSeparator = value;
                    return;

                case GlobalVariableId.ItemSeparator:
                    context.ItemSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
                    return;


                // loader:
                case GlobalVariableId.LoadedFiles:
                case GlobalVariableId.LoadPath:
                    throw ReadOnlyError(name);


                // misc:
                case GlobalVariableId.SafeLevel:
                    context.SetSafeLevel(RequireType<int>(value, name, "Fixnum"));
                    return;

                case GlobalVariableId.Verbose:
                    context.Verbose = value;
                    return;

                case GlobalVariableId.CommandLineProgramPath:
                    context.CommandLineProgramPath = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
                    return;
                
                case GlobalVariableId.KCode:
#if !SILVERLIGHT
                    if (context.RubyOptions.Compatibility == RubyCompatibility.Ruby18) {
                        // MRI calls to_str; we don't do that, it's inconsistent with other globals.
                        // If some app depends on this behavior, it will fail gracefully:
                        context.KCode = RubyEncoding.GetKCodingByNameInitial(RequireType<MutableString>(value, name, "String").GetFirstChar());
                        Utils.Log(String.Format("Set to {0}", context.KCode), "KCODE");
                        return;
                    }
#endif
                    context.ReportWarning("variable $KCODE is no longer effective");
                    return;

                case GlobalVariableId.ChildProcessExitStatus:
                    throw ReadOnlyError(name);
                    
                default:
                    throw Assert.Unreachable;
            }
        }
Beispiel #54
0
        public static object MethodMissing(RubyScope/*!*/ scope, BlockParam block, string/*!*/ self, SymbolId symbol, [NotNull]params object[]/*!*/ args) {
            string name = SymbolTable.IdToString(symbol);

            if (name.EndsWith("=", StringComparison.Ordinal) || name.EndsWith("!", StringComparison.Ordinal)) {
                throw RubyExceptions.CreateTypeError("Mutating method `{0}' called for an immutable string (System::String)", name);
            }

            // TODO: forward to MutableString until we implement the methods here:
            return KernelOps.SendMessageOpt(scope, block, ToStr(self), name, args);
        }
        public override object GetValue(RubyContext /*!*/ context, RubyScope scope)
        {
            switch (_id)
            {
            // regular expressions:
            case GlobalVariableId.MatchData:
                return((scope != null) ? scope.GetInnerMostClosureScope().CurrentMatch : null);

            case GlobalVariableId.MatchLastGroup:
                return((scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchLastGroup() : null);

            case GlobalVariableId.PreMatch:
                return((scope != null) ? scope.GetInnerMostClosureScope().GetCurrentPreMatch() : null);

            case GlobalVariableId.PostMatch:
                return((scope != null) ? scope.GetInnerMostClosureScope().GetCurrentPostMatch() : null);

            case GlobalVariableId.EntireMatch:
                return((scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchGroup(0) : null);


            // exceptions:
            case GlobalVariableId.CurrentException:
                return(context.CurrentException);

            case GlobalVariableId.CurrentExceptionBacktrace:
                return(context.GetCurrentExceptionBacktrace());


            // input:
            case GlobalVariableId.InputContent:
                return(context.InputProvider.Singleton);

            case GlobalVariableId.InputFileName:
                return(context.InputProvider.CurrentFileName);

            case GlobalVariableId.LastInputLine:
                return((scope != null) ? scope.GetInnerMostClosureScope().LastInputLine : null);

            case GlobalVariableId.LastInputLineNumber:
                return(context.InputProvider.LastInputLineNumber);

            case GlobalVariableId.CommandLineArguments:
                return(context.InputProvider.CommandLineArguments);


            // output:
            case GlobalVariableId.OutputStream:
                return(context.StandardOutput);

            case GlobalVariableId.ErrorOutputStream:
                return(context.StandardErrorOutput);

            case GlobalVariableId.InputStream:
                return(context.StandardInput);


            // separators:
            case GlobalVariableId.InputSeparator:
                return(context.InputSeparator);

            case GlobalVariableId.OutputSeparator:
                return(context.OutputSeparator);

            case GlobalVariableId.StringSeparator:
                return(context.StringSeparator);

            case GlobalVariableId.ItemSeparator:
                return(context.ItemSeparator);


            // loader:
            case GlobalVariableId.LoadPath:
                return(context.Loader.LoadPaths);

            case GlobalVariableId.LoadedFiles:
                return(context.Loader.LoadedFiles);


            // misc:
            case GlobalVariableId.SafeLevel:
                return(context.CurrentSafeLevel);

            case GlobalVariableId.Verbose:
                return(context.Verbose);

            case GlobalVariableId.KCode:
                if (context.RubyOptions.Compatibility < RubyCompatibility.Ruby19)
                {
                    var kcode = KCoding.GetKCodeName(context.KCode);
                    Utils.Log("KCODE set to " + kcode, "KCODE");
                    return(MutableString.CreateAscii(kcode));
                }

                context.ReportWarning("variable $KCODE is no longer effective");
                return(null);

            case GlobalVariableId.ChildProcessExitStatus:
                return(context.ChildProcessExitStatus);

            case GlobalVariableId.CommandLineProgramPath:
                return(context.CommandLineProgramPath);

            default:
                throw Assert.Unreachable;
            }
        }
Beispiel #56
0
        public static MutableString/*!*/ ReadLine(RubyScope/*!*/ scope, RubyIO/*!*/ self, [DefaultProtocol]MutableString separator, [DefaultProtocol]int limit) {

            // no dynamic call, modifies $_ scope variable:
            MutableString result = Gets(scope, self, separator, limit);
            if (result == null) {
                throw new EOFError("end of file reached");
            }

            return result;
        }
Beispiel #57
0
        internal MSA.LambdaExpression/*!*/ TransformBody(AstGenerator/*!*/ gen, RubyScope/*!*/ declaringScope, RubyModule/*!*/ declaringModule) {
            string encodedName = RubyExceptionData.EncodeMethodName(_name, gen.SourcePath, Location);

            AstParameters parameters;
            ScopeBuilder scope = DefineLocals(out parameters);

            var scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyMethodScope));
            var selfParameter = parameters[0];
            var blockParameter = parameters[1];

            // exclude block parameter even if it is explicitly specified:
            int visiblePrameterCountAndSignatureFlags = (parameters.Count - 2) << 2;
            if (_parameters.Block != null) {
                visiblePrameterCountAndSignatureFlags |= RubyMethodScope.HasBlockFlag;
            }
            if (_parameters.Array != null) {
                visiblePrameterCountAndSignatureFlags |= RubyMethodScope.HasUnsplatFlag;
            }

            gen.EnterMethodDefinition(
                scope,
                selfParameter,
                scopeVariable,
                blockParameter,
                _name,
                _parameters
            );

            // profiling:
            MSA.Expression profileStart, profileEnd;
            if (gen.Profiler != null) {
                int profileTickIndex = gen.Profiler.GetTickIndex(encodedName);
                var stampVariable = scope.DefineHiddenVariable("#stamp", typeof(long));
                profileStart = Ast.Assign(stampVariable, Methods.Stopwatch_GetTimestamp.OpCall());
                profileEnd = Methods.UpdateProfileTicks.OpCall(AstUtils.Constant(profileTickIndex), stampVariable);
            } else {
                profileStart = profileEnd = AstUtils.Empty();
            }

            // tracing:
            MSA.Expression traceCall, traceReturn;
            if (gen.TraceEnabled) {
                traceCall = Methods.TraceMethodCall.OpCall(
                    scopeVariable, 
                    gen.SourcePathConstant, 
                    AstUtils.Constant(Location.Start.Line)
                );

                traceReturn = Methods.TraceMethodReturn.OpCall(
                    gen.CurrentScopeVariable,
                    gen.SourcePathConstant,
                    AstUtils.Constant(Location.End.Line)
                );
            } else {
                traceCall = traceReturn = AstUtils.Empty();
            }

            MSA.ParameterExpression unwinder;
            
            MSA.Expression body = AstUtils.Try(
                profileStart,
                _parameters.TransformOptionalsInitialization(gen),
                traceCall,
                Body.TransformResult(gen, ResultOperation.Return)
            ).Filter(unwinder = Ast.Parameter(typeof(Exception), "#u"), Methods.IsMethodUnwinderTargetFrame.OpCall(scopeVariable, unwinder),
                Ast.Return(gen.ReturnLabel, Methods.GetMethodUnwinderReturnValue.OpCall(unwinder))
            ).Finally(  
                // leave frame:
                Methods.LeaveMethodFrame.OpCall(scopeVariable),
                Ast.Empty(),
                profileEnd,
                traceReturn
            );

            body = gen.AddReturnTarget(
                scope.CreateScope(
                    scopeVariable,
                    Methods.CreateMethodScope.OpCall(new AstExpressions {
                        scope.MakeLocalsStorage(),
                        scope.GetVariableNamesExpression(),
                        Ast.Constant(visiblePrameterCountAndSignatureFlags),
                        Ast.Constant(declaringScope, typeof(RubyScope)),
                        Ast.Constant(declaringModule, typeof(RubyModule)), 
                        Ast.Constant(_name),
                        selfParameter, blockParameter,
                        EnterInterpretedFrameExpression.Instance
                    }),
                    body
                )
            );

            gen.LeaveMethodDefinition();

            return CreateLambda(encodedName, parameters, body);
        }
Beispiel #58
0
 public Binding(RubyScope/*!*/ localScope) {
     Assert.NotNull(localScope);
     _localScope = localScope;
 }
        public override object GetValue(RubyContext/*!*/ context, RubyScope scope) {
            switch (_id) {
                
                // regular expressions:
                case GlobalVariableId.MatchData:
                    return (scope != null) ? scope.GetInnerMostClosureScope().CurrentMatch : null;

                case GlobalVariableId.MatchLastGroup:
                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchLastGroup() : null;

                case GlobalVariableId.MatchPrefix:
                    // TODO:
                    throw new NotImplementedException();

                case GlobalVariableId.MatchSuffix:
                    // TODO:
                    throw new NotImplementedException();

                case GlobalVariableId.EntireMatch:
                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchGroup(0) : null;


                // exceptions:
                case GlobalVariableId.CurrentException:
                    return context.CurrentException;

                case GlobalVariableId.CurrentExceptionBacktrace:
                    return context.GetCurrentExceptionBacktrace();


                // input:
                case GlobalVariableId.InputContent:
                    return context.InputProvider.Singleton;

                case GlobalVariableId.InputFileName:
                    return context.InputProvider.CurrentFileName;

                case GlobalVariableId.LastInputLine:
                    return (scope != null) ? scope.GetInnerMostClosureScope().LastInputLine : null;

                case GlobalVariableId.LastInputLineNumber:
                    return context.InputProvider.LastInputLineNumber;

                case GlobalVariableId.CommandLineArguments:
                    return context.InputProvider.CommandLineArguments;


                // output:
                case GlobalVariableId.OutputStream:
                    return context.StandardOutput;

                case GlobalVariableId.ErrorOutputStream:
                    return context.StandardErrorOutput;

                case GlobalVariableId.InputStream:
                    return context.StandardInput;


                // separators:
                case GlobalVariableId.InputSeparator:
                    return context.InputSeparator;

                case GlobalVariableId.OutputSeparator:
                    return context.OutputSeparator;

                case GlobalVariableId.StringSeparator:
                    return context.StringSeparator;

                case GlobalVariableId.ItemSeparator:
                    return context.ItemSeparator;

                
                // loader:
                case GlobalVariableId.LoadPath:
                    return context.Loader.LoadPaths;

                case GlobalVariableId.LoadedFiles:
                    return context.Loader.LoadedFiles;


                // misc:
                case GlobalVariableId.SafeLevel:
                    return context.CurrentSafeLevel;

                case GlobalVariableId.Verbose:
                    return context.Verbose;

                case GlobalVariableId.KCode:
#if !SILVERLIGHT
                    if (context.RubyOptions.Compatibility == RubyCompatibility.Ruby18) {
                        return MutableString.Create(KCoding.GetKCodeName(context.KCode));
                    }
#endif
                    context.ReportWarning("variable $KCODE is no longer effective");
                    return null;

                case GlobalVariableId.ChildProcessExitStatus:
                    return context.ChildProcessExitStatus;

                case GlobalVariableId.CommandLineProgramPath:
                    return context.CommandLineProgramPath;

                default:
                    throw Assert.Unreachable;
            }
        }
Beispiel #60
0
 public static MutableString Gets(RubyScope/*!*/ scope, RubyIO/*!*/ self) {
     return Gets(scope, self, scope.RubyContext.InputSeparator, -1);
 }