예제 #1
0
        protected long DoFiber(RCRunner runner, RCClosure closure, RCValue code)
        {
            long      fiber = Interlocked.Increment(ref _fiber);
            RCBot     bot   = runner.GetBot(closure.Bot);
            RCClosure next  = FiberClosure(bot, fiber, closure, code);

            bot.ChangeFiberState(fiber, "start");
            RCSystem.Log.Record(closure, "fiber", fiber, "start", "");

            // This creates a separate stream of execution (fiber) from the
            // one that called this method.
            // When it is done it will naturally try to return its result
            // back to the original calling fiber.  But the Next method on the
            // fiber operator will see this happening and call FiberDone instead.
            runner.Continue(null, next);
            return(fiber);
        }
예제 #2
0
        public static void DoYield(RCRunner runner, RCClosure closure, RCValue result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }
            // Check to see if this fiber was killed before moving on
            RCBot bot = runner.GetBot(closure.Bot);

            if (bot.IsFiberDone(closure.Fiber))
            {
                runner.Continue(closure, null);
                return;
            }
            // Do not permit any further changes to result or its children values.
            result.Lock();
            RCClosure next = closure.Code.Next(runner, closure, closure, result);

            if (next == null)
            {
                result = closure.Code.Finish(runner, closure, result);
                bot.ChangeFiberState(closure.Fiber, "done");
                RCSystem.Log.Record(closure, "fiber", closure.Fiber, "done", "");
                if (closure.Fiber == 0 && closure.Bot == 0)
                {
                    runner.Finish(closure, result);
                }
                // This will handle fibers that wake up from some suspended state
                // without realizing that they have been killed.
                else
                {
                    bot.FiberDone(runner, closure.Bot, closure.Fiber, result);
                }
                // Remove closure from the pending queue.
                runner.Continue(closure, null);
            }
            else
            {
                runner.Continue(closure, next);
            }
        }
예제 #3
0
        public void Invoke(RCRunner runner, RCClosure closure, string name, object left, object right)
        {
            OverloadValue overload;
            Type          ltype = left.GetType();
            Type          rtype = right.GetType();
            Type          ctype = right.GetType();

            try
            {
                if (_dispatch.TryGetValue(new OverloadKey(name, ctype, ltype, rtype), out overload))
                {
                    RCBot  bot   = runner.GetBot(closure.Bot);
                    object state = bot.GetModule(overload.Module);
                    overload.Implementation.Invoke(state, new object[] { runner, closure, left, right });
                }
                else if (_dispatch.TryGetValue(new OverloadKey(name, typeof(object), ltype, rtype),
                                               out overload))
                {
                    RCBot  bot   = runner.GetBot(closure.Bot);
                    object state = bot.GetModule(overload.Module);
                    overload.Implementation.Invoke(state, new object[] { runner, closure, left, right });
                }
                else if (_dispatch.TryGetValue(new OverloadKey(name,
                                                               typeof(object),
                                                               typeof(object),
                                                               rtype),
                                               out overload))
                {
                    RCBot  bot   = runner.GetBot(closure.Bot);
                    object state = bot.GetModule(overload.Module);
                    overload.Implementation.Invoke(state, new object[] { runner, closure, left, right });
                }
                else if (_dispatch.TryGetValue(new OverloadKey(name,
                                                               typeof(object),
                                                               ltype,
                                                               typeof(object)),
                                               out overload))
                {
                    RCBot  bot   = runner.GetBot(closure.Bot);
                    object state = bot.GetModule(overload.Module);
                    overload.Implementation.Invoke(state, new object[] { runner, closure, left, right });
                }
                else if (_dispatch.TryGetValue(new OverloadKey(name,
                                                               typeof(object),
                                                               typeof(object),
                                                               typeof(object)),
                                               out overload))
                {
                    RCBot  bot   = runner.GetBot(closure.Bot);
                    object state = bot.GetModule(overload.Module);
                    overload.Implementation.Invoke(state, new object[] { runner, closure, left, right });
                }
                else if (_dispatch.TryGetValue(new OverloadKey(name,
                                                               typeof(object),
                                                               ltype,
                                                               typeof(RCOperator)),
                                               out overload))
                {
                    RCBot  bot   = runner.GetBot(closure.Bot);
                    object state = bot.GetModule(overload.Module);
                    overload.Implementation.Invoke(state, new object[] { runner, closure, left, right });
                }
                else
                {
                    throw RCException.Overload(closure, name, left, right);
                }
            }
            catch (TargetInvocationException tiex)
            {
                Exception ex = tiex.GetBaseException();
                if (ex is RCException)
                {
                    throw ex;
                }
                else
                {
                    // You have to pass the tiex, not ex here so that the interior stack trace will
                    // be
                    // preserved when/if it is rethrown.
                    throw new RCException(closure, tiex, RCErrors.Native, ThrowMessage(name, ex));
                }
            }
        }