Exemple #1
0
        public SourceUnit(PhpSourceFile /*!*/ sourceFile, Encoding /*!*/ encoding, ILineBreaks /*!*/ lineBreaks)
        {
            Debug.Assert(sourceFile != null && encoding != null);
            Debug.Assert(lineBreaks != null);

            this.sourceFile      = sourceFile;
            this.encoding        = encoding;
            this.innerLineBreaks = lineBreaks;
            this.naming          = new NamingContext(null, null);
        }
Exemple #2
0
 public void RemoveFrame()
 {
     Top          -= ArgCount;
     TypesTop     -= TypeArgCount;
     ArgCount      = 0;
     TypeArgCount  = 0;
     Callback      = false;
     Variables     = null;
     NamingContext = null;
     //LateStaticBindType = null;
 }
Exemple #3
0
 internal void RestoreCallState(CallState old)
 {
     TypeArgCount       = old.TypeCount;
     ArgCount           = old.ArgCount;
     Callback           = old.Callback;
     CalleeName         = old.CalleeName;
     Variables          = old.Variables;
     NamingContext      = old.NamingContext;
     AllowProtectedCall = old.AllowProtectedCall;
     LateStaticBindType = old.LateStaticBindType;
 }
Exemple #4
0
 public CallState(int argCount, int typeCount, Dictionary <string, object> variables, NamingContext namingContext,
                  string calleeName, bool callback, bool allowProtectedCall, DTypeDesc lateStaticBindType)
 {
     this.ArgCount           = argCount;
     this.TypeCount          = typeCount;
     this.Variables          = variables;
     this.NamingContext      = namingContext;
     this.CalleeName         = calleeName;
     this.Callback           = callback;
     this.AllowProtectedCall = allowProtectedCall;
     this.LateStaticBindType = lateStaticBindType;
 }
Exemple #5
0
        public static bool Assert(
            object assertion,
            ScriptContext context,
            Dictionary <string, object> definedVariables,
            DObject self,
            DTypeDesc includer,
            string containingSourcePath,
            int line,
            int column,
            int containerId,
            NamingContext namingContext)
        {
            object result;
            string code;

            // skips asserts if not active:
            if (!context.Config.Assertion.Active)
            {
                return(true);
            }

            if ((code = PhpVariable.AsString(assertion)) != null)
            {
                // disables error reporting if eval should be quite:
                if (context.Config.Assertion.Quiet)
                {
                    context.DisableErrorReporting();
                }

                SourceCodeDescriptor descriptor = new SourceCodeDescriptor(containingSourcePath, containerId, line, column);

                // evaluates the expression:
                result = EvalInternal("return ", code, ";", EvalKinds.Assert, context, definedVariables, self, includer, descriptor, false, namingContext);

                // restores error reporting if eval have been quite:
                if (context.Config.Assertion.Quiet)
                {
                    context.EnableErrorReporting();
                }
            }
            else
            {
                result = assertion;
            }

            // checks the result of assertion:
            return(CheckAssertion(result, code, context, containingSourcePath, line, column, namingContext));
        }
Exemple #6
0
        public static object Eval(
            string code,
            bool synthetic,
            ScriptContext context,
            Dictionary <string, object> definedVariables,
            DObject self,
            DTypeDesc referringType,
            string callerRelativeSourcePath,
            int line,
            int column,
            int containerId,
            NamingContext namingContext)
        {
            EvalKinds kind = synthetic ? EvalKinds.SyntheticEval : EvalKinds.ExplicitEval;

            return(EvalInternal("", code, "", kind, context, definedVariables, self, referringType,
                                new SourceCodeDescriptor(callerRelativeSourcePath, containerId, line, column), false, namingContext));
        }
Exemple #7
0
        public int MakeArgsAware(int encodedFormalCount)
        {
            int param_count = encodedFormalCount & 0xffff;

            PeekAllValues(param_count);
            int encoded_args_count = TypeArgCount << 16 | ArgCount;

            // store encoded formal param count on the top of the items stack:
            if (Top + 1 > Items.Length)
            {
                ResizeItems(Top + 1);
            }
            Items[Top++] = encoded_args_count;

            ArgCount      = 0;
            TypeArgCount  = 0;
            Callback      = false;
            Variables     = null;
            NamingContext = null;
            return(encoded_args_count);
        }
Exemple #8
0
        public static bool CheckAssertion(
            object assertion,
            string code,
            ScriptContext context,
            string callerRelativeSourcePath,
            int line,
            int column,
            NamingContext namingContext)
        {
            // checks assertion:
            if (assertion != null && !PhpComparer./*Default.*/ CompareEq(assertion, false))
            {
                return(true);
            }

            // calls user callback:
            if (context.Config.Assertion.Callback != null)
            {
                ApplicationConfiguration app_config = Configuration.Application;
                FullPath full_path = new FullPath(callerRelativeSourcePath, app_config.Compiler.SourceRoot);
                context.Config.Assertion.Callback.Invoke(full_path.FullFileName, line, code);
            }

            // reports a warning if required:
            if (context.Config.Assertion.ReportWarning)
            {
                PhpException.Throw(PhpError.Warning, CoreResources.GetString("assertion_failed", code));
            }

            // terminates script execution if required:
            if (context.Config.Assertion.Terminate)
            {
                throw new ScriptDiedException(0);
            }

            // assertion failed:
            return(false);
        }
        public static T Call <T>(this ScriptContext context, string /*!*/ functionName, NamingContext namingContext,
                                 Dictionary <string, object> callerLocalVariables, params object[] arguments)
            where T : class
        {
            PhpReference rf = context.Call(functionName, namingContext, callerLocalVariables, arguments);

            if (rf.Value == null)
            {
                return(null);
            }
            else
            {
                return(DuckTyping.Instance.ImplementDuckType <T>(rf.Value));
            }
        }
        /// <summary>
        /// Creates new object with given class name, naming context and arguments and then wraps it into
        /// a duck type specified in generic type arguments.
        /// </summary>
        /// <typeparam name="T">Duck type interface to be used for wrapping.</typeparam>
        /// <param name="className">Class name which will be used for new object creation.</param>
        /// <param name="namingContext">Naming context.</param>
        /// <param name="ctorArguments">Constructor arguments to be used.</param>
        /// <returns>Dynamic object wrapped into static wrapper.</returns>
        public static T NewObject <T>(this ScriptContext context, string /*!*/ className, NamingContext namingContext, params object[] ctorArguments)
        {
            //create new argument array and dig wrapped values out of it
            object[] newCtorArgs = new object[ctorArguments.Length];

            for (int i = 0; i < newCtorArgs.Length; i++)
            {
                IDuckType duck = ctorArguments[i] as IDuckType;
                if (duck != null)
                {
                    newCtorArgs[i] = duck.OriginalObject;
                }
                else
                {
                    newCtorArgs[i] = ctorArguments[i];
                }
            }

            object o = context.NewObject(className, namingContext, newCtorArgs);

            return(DuckTyping.Instance.ImplementDuckType <T>(o));
        }
Exemple #11
0
        /// <summary>
        /// Attempts to bind this callback to its target.
        /// </summary>
        /// <param name="quiet"><B>true</B> of no errors should be thrown, <B>false</B> otherwise.</param>
        /// <param name="nameContext">Current <see cref="NamingContext"/> for function and class name resolution.</param>
        /// <param name="caller">Current class context or a <see cref="UnknownTypeDesc"/> if the class context
        /// should be determined ad-hoc.</param>
        /// <returns><B>True</B> if the callback was successfully bound, <B>false</B> if an error occured.</returns>
        public bool Bind(bool quiet, DTypeDesc caller, NamingContext nameContext)
        {
            if (IsInvalid)
            {
                return(false);
            }

            switch (state)
            {
            case State.UnboundFunction:
            {
                if (context == null)
                {
                    context = ScriptContext.CurrentContext;
                }

                routineDesc = context.ResolveFunction(targetName, nameContext, quiet);
                if (routineDesc == null)
                {
                    return(false);
                }

                state = State.Bound;
                return(true);
            }

            case State.UnboundStaticMethod:
            {
                if (context == null)
                {
                    context = ScriptContext.CurrentContext;
                }

                if (caller != null && caller.IsUnknown)
                {
                    callingContext = PhpStackTrace.GetClassContext();
                }
                else
                {
                    callingContext = caller;
                }

                // try to find the CLR method

                // find the class according to className
                ResolveTypeFlags flags = ResolveTypeFlags.UseAutoload;
                if (!quiet)
                {
                    flags |= ResolveTypeFlags.ThrowErrors;
                }

                DTypeDesc type = context.ResolveType(className, nameContext, callingContext, null, flags);
                if (type == null)
                {
                    return(false);
                }

                // find the method
                bool is_caller_method;
                lateStaticBindType = type;
                routineDesc        = Operators.GetStaticMethodDesc(type, targetName,
                                                                   ref instance, callingContext, context, quiet, false, out is_caller_method);

                if (routineDesc == null)
                {
                    return(false);
                }

                if (instance != null)
                {
                    dummyInstance = true;
                }
                state = is_caller_method ? State.BoundToCaller : State.Bound;
                return(true);
            }

            case State.UnboundInstanceMethod:
            {
                if (caller != null && caller.IsUnknown)
                {
                    callingContext = PhpStackTrace.GetClassContext();
                }
                else
                {
                    callingContext = caller;
                }

                // ask the instance for a handle to the method
                bool is_caller_method;
                routineDesc = instance.GetMethodDesc(targetName, callingContext, quiet, out is_caller_method);
                if (routineDesc == null)
                {
                    return(false);
                }

                state = (is_caller_method ? State.BoundToCaller : State.Bound);
                return(true);
            }
            }
            return(true);
        }
Exemple #12
0
        /// <summary>
        /// Implements PHP <c>eval</c> construct with given code prefix and suffix.
        /// A result of concatanation prefix + code + suffix is compiled.
        /// Prefix should contain no new line characters.
        /// </summary>
        internal static object EvalInternal(
            string prefix,
            string code,
            string suffix,
            EvalKinds kind,
            ScriptContext /*!*/ scriptContext,
            Dictionary <string, object> localVariables,
            DObject self,
            DTypeDesc referringType,
            SourceCodeDescriptor descriptor,
            bool entireFile,
            NamingContext namingContext)
        {
            Debug.Assert(prefix != null && suffix != null);

            // composes code to be compiled:
            code = String.Concat(prefix, code, suffix);

            TransientAssemblyBuilder assembly_builder = scriptContext.ApplicationContext.TransientAssemblyBuilder;

            // looks up the cache:
            TransientModule module = assembly_builder.TransientAssembly.GetModule(scriptContext, referringType, code, descriptor);

            if (module == null)
            {
                // double checked lock,
                // if module != null, it is definitely completed
                // since module is added into TransientAssembly at the end
                // of assembly_builder.Build
                lock (assembly_builder.TransientAssembly)
                {
                    // lookup again, since it could be added into TransientAssembly while lock
                    module = assembly_builder.TransientAssembly.GetModule(scriptContext, referringType, code, descriptor);

                    if (module == null)
                    {
                        if (kind == EvalKinds.SyntheticEval)
                        {
                            Debug.WriteLine("SYN EVAL", "Eval cache missed: '{0}'", code.Substring(0, Math.Max(code.IndexOf('{'), 0)).TrimEnd());
                        }
                        else
                        {
                            Debug.WriteLine("EVAL", "Eval cache missed: '{0}'({1},{2})", descriptor.ContainingSourcePath, descriptor.Line, descriptor.Column);
                        }

                        CompilerConfiguration config = new CompilerConfiguration(Configuration.Application);

                        CompilationContext context = new CompilationContext(scriptContext.ApplicationContext, null, config,
                                                                            new EvalErrorSink(-prefix.Length, config.Compiler.DisabledWarnings, config.Compiler.DisabledWarningNumbers),
                                                                            scriptContext.WorkingDirectory);

                        TransientCompilationUnit unit = assembly_builder.Build(code, descriptor, kind, context,
                                                                               scriptContext, referringType, namingContext, entireFile);

                        // compilation failed:
                        if (unit == null)
                        {
                            return(false);
                        }
                        module = unit.TransientModule;
                    }
                }
            }

            // activates unconditionally declared types, functions and constants:
            module.TransientCompilationUnit.Declare(scriptContext);

            return(module.Main(scriptContext, localVariables, self, referringType, true));
        }