Ejemplo n.º 1
0
 private static PValue _invokeHandler(StackContext sctx, PValue handler, PValue datum,
     bool performSubCall)
 {
     var handlerArgv = datum != null ? new[] {datum} : Runtime.EmptyPValueArray;
     return performSubCall
         ? CallSubPerform.RunStatically(sctx, handler, handlerArgv,
             useIndirectCallAsFallback: true)
         : handler.IndirectCall(sctx, handlerArgv);
 }
Ejemplo n.º 2
0
        public static PValue RunStatically(StackContext sctx, PValue fpv, PValue[] iargs,
            bool useIndirectCallAsFallback)
        {
            IStackAware f;
            IMaybeStackAware m;
            CilClosure cilClosure;
            PFunction func = null;
            PVariable[] sharedVars = null;

            PValue result;
            ReturnMode returnMode;

            if ((cilClosure = fpv.Value as CilClosure) != null)
            {
                func = cilClosure.Function;
                sharedVars = cilClosure.SharedVariables;
            }

            if ((func = func ?? fpv.Value as PFunction) != null && func.HasCilImplementation)
            {
                func.CilImplementation.Invoke(
                    func, CilFunctionContext.New(sctx, func), iargs, sharedVars ?? new PVariable[0],
                    out result, out returnMode);
            }
            else if ((f = fpv.Value as IStackAware) != null)
            {
                //Create stack context, let the engine execute it
                var subCtx = f.CreateStackContext(sctx, iargs);
                sctx.ParentEngine.Process(subCtx);
                result = subCtx.ReturnValue;
                returnMode = subCtx.ReturnMode;
            }
            else if ((m = fpv.Value as IMaybeStackAware) != null)
            {
                StackContext subCtx;
                if (m.TryDefer(sctx, iargs, out subCtx, out result))
                {
                    sctx.ParentEngine.Process(subCtx);
                    result = subCtx.ReturnValue;
                    returnMode = subCtx.ReturnMode;
                }
                else if (useIndirectCallAsFallback)
                {
                    returnMode = ReturnMode.Exit;
                }
                else
                {
                    throw new PrexoniteException(
                        string.Format(
                            "Invocation of {0} did not produce a valid return mode. " +
                                "Only Prexonite functions have a return mode.",
                            fpv.CallToString(sctx)));
                }
            }
            else if (useIndirectCallAsFallback)
            {
                result = fpv.IndirectCall(sctx, iargs);
                returnMode = ReturnMode.Exit;
            }
            else
            {
                throw new PrexoniteException(
                    "call\\sub\\perform requires its argument to be stack aware.");
            }

            return new PValueKeyValuePair(sctx.CreateNativePValue(returnMode), result);
        }