Ejemplo n.º 1
0
        /// <summary>
        /// Creates a new PHP stack frame.
        /// </summary>
        /// <param name="context">A script context.</param>
        /// <param name="frame">The respective CLR frame.</param>
        /// <param name="kind">A kind of the frame.</param>
        internal PhpStackFrame(ScriptContext /*!*/ context, StackFrame /*!*/ frame, FrameKinds kind)
        {
            Debug.Assert(context != null && frame != null && kind != FrameKinds.Invisible);

            this.frame = frame;
            this.kind  = kind;

            MethodBase method = frame.GetMethod();

            if (kind == FrameKinds.ClassLibraryFunction)
            {
                this.name = ImplementsFunctionAttribute.Reflect(method).Name;

                SetDebugInfo(frame);
            }
            else
            {
                Type type = method.DeclaringType;

                int eval_id = TransientAssembly.InvalidEvalId;

                if (type != null && context.ApplicationContext.IsTransientRealType(type))
                {
                    // gets [PhpEvalId] attribute defined on the type:
                    object[] attrs = type.GetCustomAttributes(typeof(PhpEvalIdAttribute), false);
                    eval_id = ((PhpEvalIdAttribute)attrs[0]).Id;

                    ErrorStackInfo info = new ErrorStackInfo();

                    PhpStackTrace.FillEvalStackInfo(context, eval_id, ref info, false);

                    this.line   = info.Line;
                    this.column = info.Column;
                    this.file   = info.File;
                    this.name   = info.Caller;
                }
                else
                {
                    SetDebugInfo(frame);
                }

                // the caller has already been set by FillEvalStackInfo
                // if it is not an eval main:
                if (!(eval_id != TransientAssembly.InvalidEvalId && PhpScript.IsScriptType(type) && kind == FrameKinds.Main))
                {
                    if (this.name == ScriptModule.MainHelperName)
                    {
                        this.name = "{main}";
                    }
                    else
                    {
                        int j;
                        PhpScript.ParseMDeclName(method.Name, out this.name, out j);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determines whether a specified method whose declaring type is a script type is a Main helper.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <param name="parameters">GetUserEntryPoint parameters (optimization). Can be <B>null</B> reference.</param>
        /// <returns>Whether a specified method is an arg-less stub.</returns>
        internal static bool IsMainHelper(MethodInfo /*!*/ method, ParameterInfo[] parameters)
        {
            Debug.Assert(method != null && PhpScript.IsScriptType(method.DeclaringType));

            if (method.Name != ScriptModule.MainHelperName)
            {
                return(false);
            }
            if (parameters == null)
            {
                parameters = method.GetParameters();
            }
            return(parameters.Length == 5 && parameters[4].ParameterType == Emit.Types.Bool[0]);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Traces the calling stack to discover current PHP class context.
        /// </summary>
        /// <returns><see cref="Type"/> of the PHP class that represents current class context for this thread or
        /// <B>null</B> if this thread is executing in a function or startup Main context.</returns>
        public static DTypeDesc GetClassContext()
        {
            // SILVERLIGHT: Todo Todo .. ? what to do here ?
#if !SILVERLIGHT
            StackTrace stack_trace = new StackTrace(1);
            int        frame_count = stack_trace.FrameCount;

            for (int i = 0; i < frame_count; i++)
            {
                StackFrame stack_frame = stack_trace.GetFrame(i);

                MethodBase method = stack_frame.GetMethod();
                Type       type   = method.DeclaringType;
                if (type != null)
                {
                    if (PhpType.IsPhpRealType(type))
                    {
                        return(DTypeDesc.Create(type));
                    }

                    MethodInfo minfo = method as MethodInfo;
                    if (minfo != null)
                    {
                        ParameterInfo[] parameters = minfo.GetParameters();
                        if (!PhpFunctionUtils.IsArglessStub(minfo, parameters) &&
                            PhpScript.IsScriptType(minfo.DeclaringType) && !PhpScript.IsMainHelper(minfo, parameters))
                        {
                            return(null);
                        }
                        // if the method is a helper method (Main, an arg-less overload, a constructor, etc.),
                        // continue with the trace
                    }
                }
            }
#endif
            return(null);
        }