Ejemplo n.º 1
0
        private Dictionary <string, Pastel.PastelCompiler> GenerateLibraryParseTree(
            Platform.AbstractPlatform platform,
            Dictionary <string, object> constantFlags,
            IInlineImportCodeLoader codeLoader,
            ICollection <LibraryMetadata> relevantLibraries,
            Pastel.PastelCompiler sharedScope)
        {
            using (new PerformanceSection("VmGenerator.GenerateLibraryParseTree"))
            {
                Dictionary <string, Pastel.PastelCompiler> libraries = new Dictionary <string, Pastel.PastelCompiler>();

                foreach (LibraryMetadata libraryMetadata in relevantLibraries)
                {
                    LibraryExporter library = LibraryExporter.Get(libraryMetadata, platform);

                    Dictionary <string, object> constantsLookup = Util.MergeDictionaries <string, object>(constantFlags, library.CompileTimeConstants);

                    Pastel.PastelCompiler compiler = new Pastel.PastelCompiler(
                        true,
                        sharedScope,
                        constantsLookup,
                        codeLoader,
                        library.GetReturnTypesForNativeMethods(),
                        library.GetArgumentTypesForNativeMethods());
                    libraries[library.Metadata.ID] = compiler;

                    Dictionary <string, string> supplementalCode = library.Metadata.GetSupplementalTranslatedCode();
                    Dictionary <string, string> translatedCode   = library.GetNativeCode();
                    Dictionary <string, string> structCode       = library.Metadata.GetStructFilesCode();
                    // need to load from the actual Library instance, which could have come from either CRAYON_HOME or source

                    string registryCode = library.Metadata.GetRegistryCode();
                    if (registryCode == null)
                    {
                        if (supplementalCode.Count > 0 || translatedCode.Count > 0)
                        {
                            throw new InvalidOperationException("The library '" + library.Metadata.ID + "' has translated code but no function_registry.pst file.");
                        }
                    }
                    else
                    {
                        compiler.CompileBlobOfCode("LIB:" + library.Metadata.ID + "/function_registry.pst", registryCode);

                        foreach (string structFile in structCode.Keys)
                        {
                            string code = structCode[structFile];
                            compiler.CompileBlobOfCode("LIB:" + library.Metadata.ID + "/structs/" + structFile, code);
                        }

                        foreach (string supplementalFile in supplementalCode.Keys)
                        {
                            string code = supplementalCode[supplementalFile];
                            compiler.CompileBlobOfCode("LIB:" + library.Metadata.ID + "/supplemental/" + supplementalFile, code);
                        }
                        foreach (string translatedFile in translatedCode.Keys)
                        {
                            string code = translatedCode[translatedFile];
                            compiler.CompileBlobOfCode("LIB:" + library.Metadata.ID + "/translate/" + translatedFile, code);
                        }
                        compiler.Resolve();
                    }
                }

                return(libraries);
            }
        }
Ejemplo n.º 2
0
        private List <Platform.LibraryForExport> GetLibrariesForExport(
            Platform.AbstractPlatform platform,
            Dictionary <string, LibraryMetadata> librariesById,
            Dictionary <string, object> constantFlags,
            IInlineImportCodeLoader codeLoader,
            Pastel.PastelCompiler vm)
        {
            using (new PerformanceSection("VmGenerator.GetLibrariesForExport"))
            {
                Dictionary <string, Pastel.PastelCompiler> libraryCompilation = this.GenerateLibraryParseTree(
                    platform,
                    constantFlags,
                    codeLoader,
                    librariesById.Values,
                    vm);

                List <Platform.LibraryForExport>     libraries     = new List <Platform.LibraryForExport>();
                Dictionary <string, LibraryExporter> libraryByName = new Dictionary <string, LibraryExporter>();
                foreach (string libraryId in libraryCompilation.Keys.OrderBy(s => s))
                {
                    LibraryExporter library = LibraryExporter.Get(librariesById[libraryId], platform);
                    libraryByName[library.Metadata.ID] = library;
                    Platform.LibraryForExport libraryForExport = this.CreateLibraryForExport(
                        library.Metadata.ID,
                        library.Metadata.Version,
                        libraryCompilation[library.Metadata.ID],
                        library.Resources);
                    libraries.Add(libraryForExport);
                }

                // Now that all libraries are read and initialized, go through and resolve all deferred DLL's that required all libraries to be loaded.
                foreach (Platform.LibraryForExport lfe in libraries)
                {
                    foreach (Platform.ExportEntity ee in lfe.ExportEntities.GetValueEnumerator())
                    {
                        if (ee.DeferredFileOutputBytesLibraryName != null)
                        {
                            LibraryExporter sourceLibrary;
                            if (!libraryByName.TryGetValue(ee.DeferredFileOutputBytesLibraryName, out sourceLibrary))
                            {
                                throw new InvalidOperationException("The library '" + lfe.Name + "' makes reference to another library '" + ee.DeferredFileOutputBytesLibraryName + "' which could not be found.");
                            }

                            string resourcePath = "resources/" + ee.DeferredFileOutputBytesLibraryPath;
                            byte[] dllFile      = sourceLibrary.Metadata.ReadFileBytes(resourcePath);
                            if (dllFile == null)
                            {
                                throw new InvalidOperationException("Could not find file: '" + resourcePath + "' in library '" + sourceLibrary.Metadata.ID + "'");
                            }
                            ee.FileOutput = new FileOutput()
                            {
                                Type          = FileOutputType.Binary,
                                BinaryContent = dllFile
                            };
                        }
                    }
                }

                return(libraries);
            }
        }
Ejemplo n.º 3
0
        private Dictionary <string, PastelContext> GenerateLibraryParseTree(
            Platform.AbstractPlatform platform,
            Dictionary <string, object> constantFlags,
            IInlineImportCodeLoader codeLoader,
            ICollection <LibraryMetadata> relevantLibraries,
            PastelContext sharedScope)
        {
            using (new PerformanceSection("VmGenerator.GenerateLibraryParseTree"))
            {
                Dictionary <string, PastelContext> libraries = new Dictionary <string, PastelContext>();

                foreach (LibraryMetadata libraryMetadata in relevantLibraries)
                {
                    LibraryExporter library = LibraryExporter.Get(libraryMetadata, platform);

                    Dictionary <string, object> constantsLookup = Util.MergeDictionaries <string, object>(constantFlags, library.CompileTimeConstants);

                    List <ExtensibleFunction> libraryFunctions = library.GetPastelExtensibleFunctions();

                    if (!libraryMetadata.IsMoreThanJustEmbedCode)
                    {
                        continue;
                    }

                    PastelContext context = new PastelContext(platform.Language, codeLoader);
                    Dictionary <string, string> exFnTranslations = library.GetExtensibleFunctionTranslations(platform);
                    foreach (ExtensibleFunction exFn in libraryFunctions)
                    {
                        string exFnTranslation = null;
                        if (exFnTranslations.ContainsKey(exFn.Name))
                        {
                            exFnTranslation = exFnTranslations[exFn.Name];
                        }
                        else if (exFnTranslations.ContainsKey("$" + exFn.Name))
                        {
                            exFnTranslation = exFnTranslations["$" + exFn.Name];
                        }

                        context.AddExtensibleFunction(exFn, exFnTranslation);
                    }
                    context.AddDependency(sharedScope);
                    foreach (string constKey in constantsLookup.Keys)
                    {
                        context.SetConstant(constKey, constantsLookup[constKey]);
                    }

                    libraries[library.Metadata.ID] = context;

                    Dictionary <string, string> supplementalCode = library.Metadata.GetSupplementalTranslatedCode();
                    Dictionary <string, string> translatedCode   = library.GetNativeCode();
                    Dictionary <string, string> structCode       = library.Metadata.GetStructFilesCode();
                    // need to load from the actual Library instance, which could have come from either CRAYON_HOME or source

                    string registryCode = library.Metadata.GetRegistryCode();
                    if (registryCode == null)
                    {
                        if (supplementalCode.Count > 0 || translatedCode.Count > 0)
                        {
                            throw new InvalidOperationException("The library '" + library.Metadata.ID + "' has translated code but no function_registry.pst file.");
                        }
                    }
                    else
                    {
                        string filename = "LIB:" + library.Metadata.ID + "/function_registry.pst";
                        context.CompileCode(filename, registryCode);

                        foreach (string structFile in structCode.Keys)
                        {
                            filename = "LIB:" + library.Metadata.ID + "/structs/" + structFile;
                            context.CompileCode(filename, structCode[structFile]);
                        }

                        foreach (string supplementalFile in supplementalCode.Keys)
                        {
                            filename = "LIB:" + library.Metadata.ID + "/supplemental/" + supplementalFile;
                            context.CompileCode(filename, supplementalCode[supplementalFile]);
                        }
                        foreach (string translatedFile in translatedCode.Keys)
                        {
                            filename = "LIB:" + library.Metadata.ID + "/translate/" + translatedFile;
                            context.CompileCode(filename, translatedCode[translatedFile]);
                        }

                        context.FinalizeCompilation();
                    }
                }

                return(libraries);
            }
        }