예제 #1
0
        /// <summary>
        /// Called before 'Compile' to initialize module &amp; assembly builders, so they can be used by the caller.
        /// </summary>
        internal bool PreCompile(CompilationContext /*!*/ context, ScriptContext /*!*/ scriptContext,
                                 SourceCodeDescriptor descriptor, EvalKinds kind, DTypeDesc referringType)
        {
            Debug.Assert(descriptor.Line == this.sourceUnit.Line);
            Debug.Assert(descriptor.Column == this.sourceUnit.Column);

            this.resolvingScriptContext = scriptContext;
            this.referringType          = referringType;

            // TODO: isDynamic is tricky...
            //  .. we need to define module_builder before any type/etc.. is reduced from the parser
            //  .. but we don't know whether it will be dynamic in advance!

            this.assembly_builder = scriptContext.ApplicationContext.TransientAssemblyBuilder;
            this.module_builder   = assembly_builder.DefineModule(this, context.Config.Compiler.Debug,
                                                                  descriptor.ContainingTransientModuleId, kind, descriptor.ContainingSourcePath);
            this.module   = module_builder;
            this.evalKind = kind;

            sourceUnit.Parse(
                context.Errors, this,
                context.Config.Compiler.LanguageFeatures);

            if (context.Errors.AnyFatalError)
            {
                return(false);
            }

            // any declaration implies non-dynamicity:
            // TODO: this mode needs to be checked...
            // isDynamic = types == null && functions == null && constants == null;

            return(true);
        }
예제 #2
0
        public ApplicationContext(bool lazyFullReflection, bool reflectionOnly, bool createTransientBuilder)
        {
            this.lazyFullReflection = lazyFullReflection;

            this.assemblyLoader           = new AssemblyLoader(this, reflectionOnly);
            this.transientAssemblyBuilder = createTransientBuilder ? new TransientAssemblyBuilder(this) : null;

            this.types     = new Dictionary <string, DTypeDesc>(StringComparer.OrdinalIgnoreCase);
            this.functions = new Dictionary <string, DRoutineDesc>(StringComparer.OrdinalIgnoreCase);
            this.constants = new DualDictionary <string, DConstantDesc>(null, StringComparer.OrdinalIgnoreCase);

#if !SILVERLIGHT
            this.scriptLibraryDatabase = new ScriptLibraryDatabase(this);
#endif

            PopulateTables();
        }
예제 #3
0
        internal TransientModuleBuilder /*!*/ DefineModule(TransientAssemblyBuilder /*!*/ assemblyBuilder,
                                                           TransientCompilationUnit /*!*/ compilationUnit, int containerId, EvalKinds kind, string sourcePath)
        {
            TransientModule container = GetModule(containerId);

            int new_id;

            rwLock.EnterWriteLock();

            try
            {
                // reserve slot in the module list:
                new_id = modules.Count;
                modules.Add(null);
            }
            finally
            {
                rwLock.ExitWriteLock();
            }

            return(new TransientModuleBuilder(new_id, kind, compilationUnit, assemblyBuilder, container, sourcePath));
        }
예제 #4
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));
        }