/// <summary> /// Called before 'Compile' to initialize module & 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); }
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(); }
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)); }
/// <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)); }