summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-12-10 14:04:29 -0500
committerGitHub <noreply@github.com>2020-12-10 14:04:29 -0500
commit4337338ed2d9525b4638f32c6b91ef61b69e41cd (patch)
treebade08ed9e1b835a73fe97b5ecb331ae940fee86
parente4a8251749cf1fbf005b045e26e25f3ef7cccb8b (diff)
Building with embedded stdlib (#1634)
* #include an absolute path didn't work - because paths were taken to always be relative. * Move reflection to reflection-api. * Slight reorg to pull out potentially Slang internal functions from the reflection API impls. * Remove visual studio projects * Fix for slang-binaries copy. * Add the visual studio projects in build/visual-studio * Remove miniz project. * Differentiate the linePath from the filePath. * Improve comment in premake5.lua + to kick of CI. * Kick CI. * Use COM compile request for calls to functions inside api-less-slang. Add static-slang project. * Fix const typo issue. * Don't include 'core' link in 'api-less-slang' * Removed static-slang lib causes problems on linux with linking. Embed Slang stdlib Added StaticBlob Added dumpSourceBytes Use ConstArrayView for the archive. At startup allow loading of zip with stdlib. Made -save-stdlib -load-stdlib take a name Added '-save-stdlib-bin-source' to save out serialized stdlib as source. * Ability enable/disable stdlib embedding. * Fix problem with moduleDecl not having module pointer set when serialized in. * Set of debugdir for slang-test and examples. * Add slang-stdlib-api.cpp * Update slang filters for VS. * Try to use pic, and -mcmodel=medium * Some more efforts ot make premake work. * WIP premake5.lua from previously working version. * Remove api-less-slang project. * Disable dllexport on gcc/clang. * Embed via slangc-bootstrap. * Fix slang-profile. Always compiles without stdlib. * Use pic "On" * Remove slangc-bootstrap and embed-stdlib-generator if embedding not required. Make bootstrap run the generators. * Improve comments in premake5.lua. Kick off another CI build. * Remove generation of stdlib source from std-lib-serialize.slang
-rw-r--r--build/visual-studio/slang/slang.vcxproj12
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters3
-rw-r--r--premake5.lua159
-rw-r--r--slang.h26
-rw-r--r--source/core/slang-blob.cpp10
-rw-r--r--source/core/slang-blob.h29
-rw-r--r--source/core/slang-hex-dump-util.cpp40
-rw-r--r--source/core/slang-hex-dump-util.h4
-rw-r--r--source/core/slang-stream.h3
-rw-r--r--source/core/slang-zip-file-system.cpp4
-rw-r--r--source/core/slang-zip-file-system.h2
-rw-r--r--source/slang/slang-api.cpp17
-rwxr-xr-xsource/slang/slang-compiler.h9
-rw-r--r--source/slang/slang-options.cpp108
-rw-r--r--source/slang/slang-repro.cpp21
-rw-r--r--source/slang/slang-stdlib-api.cpp29
-rw-r--r--source/slang/slang.cpp61
-rw-r--r--tests/serialization/std-lib-serialize.slang4
-rw-r--r--tools/slang-test/unit-test-compression.cpp2
19 files changed, 419 insertions, 124 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index 21c80b11e..9eca53310 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -98,7 +98,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
- <PreprocessorDefinitions>_DEBUG;SLANG_DYNAMIC_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;SLANG_DYNAMIC_EXPORT;SLANG_WITHOUT_EMBEDDED_STD_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..\external\spirv-headers\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<Optimization>Disabled</Optimization>
@@ -119,7 +119,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
- <PreprocessorDefinitions>_DEBUG;SLANG_DYNAMIC_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;SLANG_DYNAMIC_EXPORT;SLANG_WITHOUT_EMBEDDED_STD_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..\external\spirv-headers\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<Optimization>Disabled</Optimization>
@@ -140,7 +140,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
- <PreprocessorDefinitions>NDEBUG;SLANG_DYNAMIC_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;SLANG_DYNAMIC_EXPORT;SLANG_WITHOUT_EMBEDDED_STD_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..\external\spirv-headers\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
@@ -165,7 +165,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
- <PreprocessorDefinitions>NDEBUG;SLANG_DYNAMIC_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;SLANG_DYNAMIC_EXPORT;SLANG_WITHOUT_EMBEDDED_STD_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..\external\spirv-headers\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
@@ -416,6 +416,7 @@
<ClCompile Include="..\..\..\source\slang\slang-serialize-types.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-serialize.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-source-loc.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-stdlib-api.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-stdlib.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-syntax.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-token.cpp" />
@@ -436,6 +437,9 @@
<ProjectReference Include="..\core\core.vcxproj">
<Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
</ProjectReference>
+ <ProjectReference Include="..\miniz\miniz.vcxproj">
+ <Project>{E76ACB11-4A12-4F0A-BE1E-CE0B8836EB7F}</Project>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index d83093235..426467529 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -695,6 +695,9 @@
<ClCompile Include="..\..\..\source\slang\slang-source-loc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-stdlib-api.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-stdlib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/premake5.lua b/premake5.lua
index 79e6055c3..801847cde 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -127,6 +127,14 @@ newoption {
allowed = { { "true", "True"}, { "false", "False" } }
}
+newoption {
+ trigger = "enable-embed-stdlib",
+ description = "(Optional) If true build slang with an embedded version of the stdlib",
+ value = "bool",
+ default = "false",
+ allowed = { { "true", "True"}, { "false", "False" } }
+}
+
buildLocation = _OPTIONS["build-location"]
executeBinary = (_OPTIONS["execute-binary"] == "true")
targetDetail = _OPTIONS["target-detail"]
@@ -136,6 +144,7 @@ enableProfile = (_OPTIONS["enable-profile"] == "true")
optixPath = _OPTIONS["optix-sdk-path"]
enableOptix = not not (_OPTIONS["enable-optix"] == "true" or optixPath)
enableProfile = (_OPTIONS["enable-profile"] == "true")
+enableEmbedStdLib = (_OPTIONS["enable-embed-stdlib"] == "true")
-- This is the path where nvapi is expected to be found
@@ -308,12 +317,7 @@ function addSourceDir(path)
removefiles
{
"**/*.meta.slang.h",
- "**/slang-generated-*",
- "**/slang-ast-generated*",
- "**/slang-ref-object-generated*",
- "**/*generated.h",
- "**/*generated-macro.h"
-
+ "**/slang-*generated*.h"
}
end
@@ -499,6 +503,9 @@ function example(name)
-- They have their source code under `examples/<project-name>/`
baseSlangProject(name, "examples/" .. name)
+ -- Set up working directory to be the source directory
+ debugdir("examples/" .. name)
+
-- By default, all of our examples are GUI applications. One some
-- platforms there is no meaningful distinction between GUI and
-- command-line applications, but it is significant on Windows and MacOS
@@ -585,6 +592,8 @@ example "cpu-hello-world"
standardProject("core", "source/core")
uuid "F9BE7957-8399-899E-0C49-E714FDDD4B65"
kind "StaticLib"
+ -- We need the core library to be relocatable to be able to link with slang.so
+ pic "On"
-- For our core implementation, we want to use the most
-- aggressive warning level supported by the target, and
@@ -600,10 +609,6 @@ standardProject("core", "source/core")
addSourceDir "source/core/unix"
end
- -- We need the core library to be relocatable to be able to link with slang.so
- filter { "system:linux" }
- buildoptions{"-fPIC"}
-
--
-- The cpp extractor is a tool that scans C++ header files to extract
-- reflection like information, and generate files to handle
@@ -654,6 +659,11 @@ tool "slang-test"
uuid "0C768A18-1D25-4000-9F37-DA5FE99E3B64"
includedirs { "." }
links { "core", "slang", "miniz" }
+
+ -- We want to set to the root of the project, but that doesn't seem to work with '.'.
+ -- So set a path that resolves to the same place.
+
+ debugdir("source/..")
--
-- The reflection test harness `slang-reflection-test` is pretty
@@ -734,6 +744,7 @@ tool "gfx"
-- Unlike most of the code under `tools/`, this is a library
-- rather than a stand-alone executable.
kind "StaticLib"
+ pic "On"
includedirs { ".", "external", "source", "external/imgui" }
@@ -789,9 +800,6 @@ tool "gfx"
end
- filter { "system:linux" }
- -- might be able to do pic(true)
- buildoptions{"-fPIC"}
--
-- The `slangc` command-line application is just a very thin wrapper
@@ -944,8 +952,92 @@ generatorProject("run-generators", nil)
buildoutputs { "%{file.abspath}.cpp" }
buildinputs { "%{cfg.targetdir}/slang-embed" .. executableSuffix }
end
-
-
+
+if enableEmbedStdLib then
+ standardProject("slangc-bootstrap", "source/slangc")
+ uuid "6339BF31-AC99-4819-B719-679B63451EF0"
+ kind "ConsoleApp"
+ links { "core", "miniz" }
+
+ -- We need to run all the generators to be able to build the main
+ -- slang source in source/slang
+
+ dependson { "run-generators" }
+
+ defines {
+ -- We are going statically link Slang compiler with the slangc command line
+ "SLANG_STATIC",
+ -- This is the bootstrap to produce the embedded stdlib, so we disable to be able to bootstrap
+ "SLANG_WITHOUT_EMBEDDED_STD_LIB"
+ }
+
+ includedirs { "external/spirv-headers/include" }
+
+ -- Add all of the slang source
+ addSourceDir "source/slang"
+
+ -- On some tests with MSBuild disabling these made build work.
+ -- flags { "NoIncrementalLink", "NoPCH", "NoMinimalRebuild" }
+
+ -- The `standardProject` operation already added all the code in
+ -- `source/slang/*`, but we also want to incldue the umbrella
+ -- `slang.h` header in this prject, so we do that manually here.
+ files { "slang.h" }
+
+ files { "source/core/core.natvis" }
+
+ -- We explicitly name the prelude file(s) that we need to
+ -- compile for their embedded code, since they will not
+ -- exist at the time projects/makefiles are generated,
+ -- and thus a glob would not match anything.
+ files {
+ "prelude/slang-cuda-prelude.h.cpp",
+ "prelude/slang-hlsl-prelude.h.cpp",
+ "prelude/slang-cpp-prelude.h.cpp"
+ }
+end
+
+if enableEmbedStdLib then
+ generatorProject("embed-stdlib-generator", nil)
+
+ -- We include these, even though they are not really part of the dummy
+ -- build, so that the filters below can pick up the appropriate locations.
+
+ files
+ {
+ --
+ -- To build we need to have some source! It has to be a source file that
+ -- does not depend on anything that is generated, so we take something
+ -- from core that will compile without any generation.
+ --
+
+ "source/slang/slang-stdlib-api.cpp",
+ }
+
+ -- Only produce the embedded stdlib if that option is enabled
+
+ local executableSuffix = getExecutableSuffix()
+
+ -- We need slangc-bootstrap to build the embedded stdlib
+ dependson { "slangc-bootstrap" }
+
+ local absDirectory = path.getabsolute("source/slang")
+ local absOutputPath = absDirectory .. "/slang-stdlib-generated.h"
+
+ -- I don't know why I need a filter, but without it nothing works (!)
+ filter "files:source/slang/slang-stdlib-api.cpp"
+
+ -- Note! Has to be an absolute path else doesn't work(!)
+ buildoutputs { absOutputPath }
+
+ buildinputs { "%{cfg.targetdir}/slangc-bootstrap" .. executableSuffix }
+
+ local buildcmd = '"%{cfg.targetdir}/slangc-bootstrap" -save-stdlib-bin-source %{file.directory}/slang-stdlib-generated.h'
+
+ buildcommands { buildcmd }
+end
+
+
--
-- TODO: Slang's current `Makefile` build does some careful incantations
-- to make sure that the binaries it generates use a "relative `RPATH`"
@@ -965,16 +1057,25 @@ generatorProject("run-generators", nil)
standardProject("slang", "source/slang")
uuid "DB00DA62-0533-4AFD-B59F-A67D5B3A0808"
kind "SharedLib"
- links { "core" }
+ links { "core", "miniz"}
warnings "Extra"
flags { "FatalWarnings" }
+ pic "On"
-- The way that we currently configure things through `slang.h`,
-- we need to set a preprocessor definitions to ensure that
-- we declare the Slang API functions for *export* and not *import*.
--
defines { "SLANG_DYNAMIC_EXPORT" }
-
+
+ if enableEmbedStdLib then
+ -- We only have this dependency if we are embedding stdlib
+ dependson { "embed-stdlib-generator" }
+ else
+ -- Disable StdLib embedding
+ defines { "SLANG_WITHOUT_EMBEDDED_STD_LIB" }
+ end
+
includedirs { "external/spirv-headers/include" }
-- On some tests with MSBuild disabling these made build work.
@@ -1018,10 +1119,6 @@ standardProject("slang", "source/slang")
"{COPY} ../../../external/slang-binaries/bin/" .. targetName .. "/libslang-glslang.so %{cfg.targetdir}"
}
end
-
- filter { "system:linux" }
- -- might be able to do pic(true)
- buildoptions{"-fPIC"}
if enableProfile then
@@ -1035,8 +1132,11 @@ if enableProfile then
includedirs { "external/spirv-headers/include" }
- defines { "SLANG_STATIC" }
-
+ defines { "SLANG_STATIC",
+ -- Disable StdLib embedding
+ "SLANG_WITHOUT_EMBEDDED_STD_LIB"
+ }
+
-- The `standardProject` operation already added all the code in
-- `source/slang/*`, but we also want to incldue the umbrella
-- `slang.h` header in this prject, so we do that manually here.
@@ -1058,7 +1158,7 @@ if enableProfile then
addSourceDir "source/slang"
includedirs { "." }
- links { "core"}
+ links { "core", "miniz"}
filter { "system:linux" }
linkoptions{ "-pg" }
@@ -1069,6 +1169,7 @@ end
standardProject("miniz", nil)
uuid "E76ACB11-4A12-4F0A-BE1E-CE0B8836EB7F"
kind "StaticLib"
+ pic "On"
-- Add the files explicitly
files
@@ -1081,14 +1182,15 @@ standardProject("miniz", nil)
filter { "system:linux or macosx" }
links { "dl"}
- buildoptions{"-fPIC"}
-
+
if buildGlslang then
standardProject("slang-spirv-tools", nil)
uuid "C36F6185-49B3-467E-8388-D0E9BF5F7BB8"
kind "StaticLib"
+ pic "On"
+
includedirs { "external/spirv-tools", "external/spirv-tools/include", "external/spirv-headers/include", "external/spirv-tools-generated"}
addSourceDir("external/spirv-tools/source")
@@ -1098,8 +1200,6 @@ standardProject("slang-spirv-tools", nil)
filter { "system:linux or macosx" }
links { "dl"}
- buildoptions{"-fPIC"}
-
--
-- The single most complicated part of our build is our custom version of glslang.
-- Is not really set up to produce a shared library with a usable API, so we have
@@ -1115,6 +1215,8 @@ standardProject("slang-spirv-tools", nil)
standardProject("slang-glslang", nil)
uuid "C495878A-832C-485B-B347-0998A90CC936"
kind "SharedLib"
+ pic "On"
+
includedirs { "external/glslang", "external/spirv-tools", "external/spirv-tools/include", "external/spirv-headers/include", "external/spirv-tools-generated", "external/glslang-generated" }
defines
@@ -1159,7 +1261,6 @@ standardProject("slang-glslang", nil)
filter { "system:linux or macosx" }
links { "dl" }
- buildoptions{"-fPIC"}
diff --git a/slang.h b/slang.h
index f09f15c24..87144df86 100644
--- a/slang.h
+++ b/slang.h
@@ -195,7 +195,13 @@ convention for interface methods.
#if defined(_MSC_VER)
# define SLANG_DLL_EXPORT __declspec(dllexport)
#else
-# define SLANG_DLL_EXPORT __attribute__((__visibility__("default")))
+# if 0 && __GNUC__ >= 4
+// Didn't work on latest gcc on linux.. so disable for now
+// https://gcc.gnu.org/wiki/Visibility
+# define SLANG_DLL_EXPORT __attribute__ ((dllexport))
+# else
+# define SLANG_DLL_EXPORT __attribute__((__visibility__("default")))
+# endif
#endif
#if defined(SLANG_DYNAMIC)
@@ -3092,14 +3098,19 @@ namespace slang
*/
virtual SLANG_NO_THROW SlangResult SLANG_MCALL compileStdLib() = 0;
- /** Load the StdLib. Currently loads modules from the file system
- NOTE! API is experimental and not ready for production code
+ /** Load the StdLib. Currently loads modules from the file system.
+ @param stdLib Start address of the serialized stdlib
+ @param stdLibSizeInBytes The size in bytes of the serialized stdlib
+
+ NOTE! API is experimental and not ready for production code
*/
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadStdLib() = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadStdLib(const void* stdLib, size_t stdLibSizeInBytes) = 0;
/** Save the StdLib modules to the file system
+ @param outBlob The serialized blob containing the standard library
+
NOTE! API is experimental and not ready for production code */
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveStdLib() = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveStdLib(ISlangBlob** outBlob) = 0;
};
#define SLANG_UUID_IGlobalSession { 0xc140b5fd, 0xc78, 0x452e, { 0xba, 0x7c, 0x1a, 0x1e, 0x70, 0xc7, 0xf7, 0x1c } };
@@ -4050,6 +4061,11 @@ SLANG_EXTERN_C SLANG_API SlangResult slang_createGlobalSessionWithoutStdLib(
SlangInt apiVersion,
slang::IGlobalSession** outGlobalSession);
+/* Returns a blob that contains the serialized stdlib.
+Returns nullptr if there isn't an embedded stdlib.
+*/
+SLANG_API ISlangBlob* slang_getEmbeddedStdLib();
+
namespace slang
{
inline SlangResult createGlobalSession(
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index 4421db09a..becccf51c 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -11,4 +11,14 @@ ISlangUnknown* BlobBase::getInterface(const Guid& guid)
return (guid == IID_ISlangUnknown || guid == IID_ISlangBlob) ? static_cast<ISlangBlob*>(this) : nullptr;
}
+SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
+{
+ if (guid == IID_ISlangUnknown || guid == IID_ISlangBlob)
+ {
+ *outObject = static_cast<ISlangBlob*>(this);
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+}
+
} // namespace Slang
diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h
index d326f9c9c..c98c41563 100644
--- a/source/core/slang-blob.h
+++ b/source/core/slang-blob.h
@@ -26,6 +26,7 @@ protected:
};
/** A blob that uses a `String` for its storage.
+NOTE! Returns length *WITHOUT* terminating 0, even though there is one.
*/
class StringBlob : public BlobBase
{
@@ -191,6 +192,34 @@ protected:
};
+/** A Blob that has no ref counting and exists typically for entire execution.
+The memory it references is *not* owned by the blob.
+This is useful when a Blob is useful to represent some global immutable chunk of memory.
+*/
+class StaticBlob : public ISlangBlob
+{
+public:
+
+ // ISlangUnknown
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+
+ // ISlangBlob
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data; }
+ SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_dataCount; }
+
+ StaticBlob(const void* data, size_t dataCount):
+ m_data(data),
+ m_dataCount(dataCount)
+ {
+ }
+
+protected:
+ const void* m_data;
+ size_t m_dataCount;
+};
+
/// Create a blob that will retain (a copy of) raw data.
///
inline ComPtr<ISlangBlob> createRawBlob(void const* inData, size_t size)
diff --git a/source/core/slang-hex-dump-util.cpp b/source/core/slang-hex-dump-util.cpp
index cb7187499..b493141a1 100644
--- a/source/core/slang-hex-dump-util.cpp
+++ b/source/core/slang-hex-dump-util.cpp
@@ -53,6 +53,46 @@ static const char s_hex[] = "0123456789abcdef";
return dump(data.getBuffer(), data.getCount(), maxBytesPerLine, writer);
}
+SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer)
+{
+ const uint8_t* cur = data;
+ const uint8_t* end = data + dataCount;
+
+ while (cur < end)
+ {
+ size_t count = size_t(end - cur);
+ count = (count > size_t(maxBytesPerLine)) ? size_t(maxBytesPerLine) : count;
+
+ // each byte is output as "0xAA, "
+ // Ends with '\n"
+ const size_t lineBytes = count * (4 + 1 + 1) * count + 1;
+
+ char* startDst = writer->beginAppendBuffer(lineBytes);
+ char* dst = startDst;
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ uint8_t byte = cur[i];
+ dst[0] = '0';
+ dst[1] = 'x';
+ dst[2] = s_hex[byte >> 4];
+ dst[3] = s_hex[byte & 0xf];
+ dst[4] = ',';
+ dst[5] = ' ';
+
+ dst += 6;
+ }
+
+ *dst++ = '\n';
+
+ SLANG_RETURN_ON_FAIL(writer->endAppendBuffer(startDst, size_t(dst - startDst)));
+
+ cur += count;
+ }
+
+ return SLANG_OK;
+}
+
/* static */SlangResult HexDumpUtil::dump(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer)
{
int maxCharsPerLine = 2 * maxBytesPerLine + 1 + maxBytesPerLine + 1;
diff --git a/source/core/slang-hex-dump-util.h b/source/core/slang-hex-dump-util.h
index f38bfde78..f02728522 100644
--- a/source/core/slang-hex-dump-util.h
+++ b/source/core/slang-hex-dump-util.h
@@ -12,6 +12,10 @@ namespace Slang
struct HexDumpUtil
{
+ /// Dump out bytes in source format - as in
+ /// 0x10, 0xab,
+ static SlangResult dumpSourceBytes(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer);
+
/// Dump data to writer, with lines starting with hex data
static SlangResult dump(const List<uint8_t>& data, int numBytesPerLine, ISlangWriter* writer);
diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h
index c4064871b..730ce70be 100644
--- a/source/core/slang-stream.h
+++ b/source/core/slang-stream.h
@@ -77,6 +77,9 @@ public:
virtual bool canWrite() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Write)) != 0; }
virtual void close() SLANG_OVERRIDE { m_access = FileAccess::None; }
+ /// Get the contents
+ ConstArrayView<uint8_t> getContents() const { return ConstArrayView<uint8_t>(m_contents, m_contentsSize); }
+
MemoryStreamBase(FileAccess access = FileAccess::Read, const void* contents = nullptr, size_t contentsSize = 0):
m_access(access)
{
diff --git a/source/core/slang-zip-file-system.cpp b/source/core/slang-zip-file-system.cpp
index ea9a39445..8547f7eac 100644
--- a/source/core/slang-zip-file-system.cpp
+++ b/source/core/slang-zip-file-system.cpp
@@ -49,7 +49,7 @@ public:
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) SLANG_OVERRIDE;
// CompressedFileSystem
- virtual ArrayView<uint8_t> getArchive() SLANG_OVERRIDE;
+ virtual ConstArrayView<uint8_t> getArchive() SLANG_OVERRIDE;
virtual void setCompressionType(CompressionType type) SLANG_OVERRIDE;
ZipFileSystem();
@@ -834,7 +834,7 @@ SlangResult ZipFileSystem::createDirectory(const char* path)
return SLANG_OK;
}
-ArrayView<uint8_t> ZipFileSystem::getArchive()
+ConstArrayView<uint8_t> ZipFileSystem::getArchive()
{
// If we have anything deleted in 'Read', we need to convert to 'Write' and then back to read
if (m_mode == Mode::Read && !m_removedSet.isEmpty())
diff --git a/source/core/slang-zip-file-system.h b/source/core/slang-zip-file-system.h
index 47c7b8db3..4a95cd51c 100644
--- a/source/core/slang-zip-file-system.h
+++ b/source/core/slang-zip-file-system.h
@@ -19,7 +19,7 @@ public:
};
/// Get as an archive (that can be saved to disk)
- virtual ArrayView<uint8_t> getArchive() = 0;
+ virtual ConstArrayView<uint8_t> getArchive() = 0;
/// Set the compression - used for any subsequent items added
virtual void setCompressionType(CompressionType type) = 0;
diff --git a/source/slang/slang-api.cpp b/source/slang/slang-api.cpp
index ea6c7820b..c8b932306 100644
--- a/source/slang/slang-api.cpp
+++ b/source/slang/slang-api.cpp
@@ -4,8 +4,6 @@
#include "slang-repro.h"
-#include "../../slang-tag-version.h"
-
// implementation of C interface
SLANG_API SlangSession* spCreateSession(const char*)
@@ -25,7 +23,18 @@ SLANG_API SlangResult slang_createGlobalSession(
{
Slang::ComPtr<slang::IGlobalSession> globalSession;
SLANG_RETURN_ON_FAIL(slang_createGlobalSessionWithoutStdLib(apiVersion, globalSession.writeRef()));
- SLANG_RETURN_ON_FAIL(globalSession->compileStdLib());
+
+ // If we have the embedded stdlib, load from that, else compile it
+ ISlangBlob* stdLibBlob = slang_getEmbeddedStdLib();
+ if (stdLibBlob)
+ {
+ SLANG_RETURN_ON_FAIL(globalSession->loadStdLib(stdLibBlob->getBufferPointer(), stdLibBlob->getBufferSize()));
+ }
+ else
+ {
+ SLANG_RETURN_ON_FAIL(globalSession->compileStdLib());
+ }
+
*outGlobalSession = globalSession.detach();
return SLANG_OK;
}
@@ -64,7 +73,7 @@ SLANG_API void spDestroySession(
SLANG_API const char* spGetBuildTagString()
{
- return SLANG_TAG_VERSION;
+ return Slang::getBuildTagString();
}
SLANG_API void spAddBuiltins(
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 9e3550066..ab02a0c54 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1196,6 +1196,9 @@ namespace Slang
/// Given a target returns a downstream compiler the prelude should be taken from.
SourceLanguage getDefaultSourceLanguageForDownstreamCompiler(PassThroughMode compiler);
+ /// Get the build tag string
+ const char* getBuildTagString();
+
struct TypeCheckingCache;
/// A context for loading and re-using code modules.
@@ -2148,8 +2151,8 @@ namespace Slang
SLANG_NO_THROW SlangResult SLANG_MCALL checkPassThroughSupport(SlangPassThrough passThrough) override;
SLANG_NO_THROW SlangResult SLANG_MCALL compileStdLib() override;
- SLANG_NO_THROW SlangResult SLANG_MCALL loadStdLib() override;
- SLANG_NO_THROW SlangResult SLANG_MCALL saveStdLib() override;
+ SLANG_NO_THROW SlangResult SLANG_MCALL loadStdLib(const void* stdLib, size_t stdLibSizeInBytes) override;
+ SLANG_NO_THROW SlangResult SLANG_MCALL saveStdLib(ISlangBlob** outBlob) override;
/// Get the default compiler for a language
DownstreamCompiler* getDefaultDownstreamCompiler(SourceLanguage sourceLanguage);
@@ -2247,7 +2250,7 @@ namespace Slang
private:
- SlangResult _readBuiltinModule(Scope* scope, String moduleName);
+ SlangResult _readBuiltinModule(ISlangFileSystem* fileSystem, Scope* scope, String moduleName);
SlangResult _loadRequest(EndToEndCompileRequest* request, const void* data, size_t size);
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index ab88b489a..c3de87d87 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -16,6 +16,7 @@
#include "slang-serialize-ir.h"
#include "../core/slang-type-text-util.h"
+#include "../core/slang-hex-dump-util.h"
#include <assert.h>
@@ -175,7 +176,7 @@ struct OptionsParser
Stage impliedStage)
{
auto translationUnitIndex = rawTranslationUnits.getCount();
- auto translationUnitID = spAddTranslationUnit(compileRequest, language, nullptr);
+ auto translationUnitID = compileRequest->addTranslationUnit(language, nullptr);
// As a sanity check: the API should be returning the same translation
// unit index as we maintain internally. This invariant would only
@@ -205,10 +206,7 @@ struct OptionsParser
slangTranslationUnitIndex = addTranslationUnit(SLANG_SOURCE_LANGUAGE_SLANG, Stage::Unknown);
}
- spAddTranslationUnitSourceFile(
- compileRequest,
- rawTranslationUnits[slangTranslationUnitIndex].translationUnitID,
- path.begin());
+ compileRequest->addTranslationUnitSourceFile(rawTranslationUnits[slangTranslationUnitIndex].translationUnitID, path.begin());
// Set the translation unit to be used by subsequent entry points
currentTranslationUnitIndex = slangTranslationUnitIndex;
@@ -222,10 +220,7 @@ struct OptionsParser
translationUnitCount++;
currentTranslationUnitIndex = addTranslationUnit(language, impliedStage);
- spAddTranslationUnitSourceFile(
- compileRequest,
- rawTranslationUnits[currentTranslationUnitIndex].translationUnitID,
- path.begin());
+ compileRequest->addTranslationUnitSourceFile(rawTranslationUnits[currentTranslationUnitIndex].translationUnitID, path.begin());
}
static Profile::RawVal findGlslProfileFromPath(const String& path)
@@ -346,7 +341,7 @@ struct OptionsParser
if (ext == "slang-module" || ext == "slang-lib")
{
- spSetOutputContainerFormat(compileRequest, SLANG_CONTAINER_FORMAT_SLANG_MODULE);
+ compileRequest->setOutputContainerFormat(SLANG_CONTAINER_FORMAT_SLANG_MODULE);
requestImpl->m_containerOutputPath = path;
}
else
@@ -449,7 +444,13 @@ struct OptionsParser
}
else if (argStr == "-load-stdlib")
{
- SLANG_RETURN_ON_FAIL(session->loadStdLib());
+ String fileName;
+ SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, fileName));
+
+ // Load the file
+ ScopedAllocation contents;
+ SLANG_RETURN_ON_FAIL(File::readAllBytes(fileName, contents));
+ SLANG_RETURN_ON_FAIL(session->loadStdLib(contents.getData(), contents.getSizeInBytes()));
}
else if (argStr == "-compile-stdlib")
{
@@ -457,7 +458,29 @@ struct OptionsParser
}
else if (argStr == "-save-stdlib")
{
- SLANG_RETURN_ON_FAIL(session->saveStdLib());
+ String fileName;
+ SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, fileName));
+
+ ComPtr<ISlangBlob> blob;
+
+ SLANG_RETURN_ON_FAIL(session->saveStdLib(blob.writeRef()));
+ SLANG_RETURN_ON_FAIL(File::writeAllBytes(fileName, blob->getBufferPointer(), blob->getBufferSize()));
+ }
+ else if (argStr == "-save-stdlib-bin-source")
+ {
+ String fileName;
+ SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, fileName));
+
+ ComPtr<ISlangBlob> blob;
+
+ SLANG_RETURN_ON_FAIL(session->saveStdLib(blob.writeRef()));
+
+ StringBuilder builder;
+ StringWriter writer(&builder, 0);
+
+ SLANG_RETURN_ON_FAIL(HexDumpUtil::dumpSourceBytes((const uint8_t*)blob->getBufferPointer(), blob->getBufferSize(), 16, &writer));
+
+ File::writeAllText(fileName, builder);
}
else if (argStr == "-no-codegen")
{
@@ -465,7 +488,7 @@ struct OptionsParser
}
else if (argStr == "-dump-intermediates")
{
- spSetDumpIntermediates(compileRequest, true);
+ compileRequest->setDumpIntermediates(true);
}
else if (argStr == "-dump-intermediate-prefix")
{
@@ -489,7 +512,7 @@ struct OptionsParser
else if (argStr == "-dump-repro")
{
SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, requestImpl->m_dumpRepro));
- spEnableReproCapture(compileRequest);
+ compileRequest->enableReproCapture();
}
else if (argStr == "-dump-repro-on-error")
{
@@ -507,7 +530,7 @@ struct OptionsParser
String moduleName;
SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, moduleName));
- spSetDefaultModuleName(compileRequest, moduleName.getBuffer());
+ compileRequest->setDefaultModuleName(moduleName.getBuffer());
}
else if(argStr == "-load-repro")
{
@@ -568,7 +591,7 @@ struct OptionsParser
cacheFileSystem->setInnerFileSystem(dirFileSystem, cacheFileSystem->getUniqueIdentityMode(), cacheFileSystem->getPathStyle());
// Set as the file system
- spSetFileSystem(compileRequest, cacheFileSystem);
+ compileRequest->setFileSystem(cacheFileSystem);
}
else if (argStr == "-serial-ir")
{
@@ -635,7 +658,7 @@ struct OptionsParser
String name;
SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, name));
- SlangProfileID profileID = spFindProfile(session, name.begin());
+ SlangProfileID profileID = session->findProfile(name.begin());
if( profileID == SLANG_PROFILE_UNKNOWN )
{
sink->diagnose(SourceLoc(), Diagnostics::unknownProfile, name);
@@ -719,7 +742,7 @@ struct OptionsParser
return SLANG_FAIL;
}
- spSetPassThrough(compileRequest, passThrough);
+ compileRequest->setPassThrough(passThrough);
}
else if (argStr.getLength() >= 2 && argStr[1] == 'D')
{
@@ -750,20 +773,12 @@ struct OptionsParser
if (eqPos)
{
// If we found an `=`, we split the string...
-
- spAddPreprocessorDefine(
- compileRequest,
- String(defineStr, eqPos).begin(),
- String(eqPos+1).begin());
+ compileRequest->addPreprocessorDefine(String(defineStr, eqPos).begin(), String(eqPos+1).begin());
}
else
{
// If there was no `=`, then just #define it to an empty string
-
- spAddPreprocessorDefine(
- compileRequest,
- String(defineStr).begin(),
- "");
+ compileRequest->addPreprocessorDefine(String(defineStr).begin(), "");
}
}
else if (argStr.getLength() >= 2 && argStr[1] == 'I')
@@ -780,9 +795,7 @@ struct OptionsParser
SLANG_RETURN_ON_FAIL(tryReadCommandLineArgumentRaw(sink, arg, &argCursor, argEnd, &includeDirStr));
}
- spAddSearchPath(
- compileRequest,
- String(includeDirStr).begin());
+ compileRequest->addSearchPath(String(includeDirStr).begin());
}
//
// A `-o` option is used to specify a desired output file.
@@ -818,7 +831,7 @@ struct OptionsParser
return SLANG_FAIL;
}
- spSetLineDirectiveMode(compileRequest, mode);
+ compileRequest->setLineDirectiveMode(mode);
}
else if( argStr == "-fp-mode" || argStr == "-floating-point-mode" )
@@ -866,7 +879,7 @@ struct OptionsParser
return SLANG_FAIL;
}
- spSetOptimizationLevel(compileRequest, level);
+ compileRequest->setOptimizationLevel(level);
}
// Note: unlike with `-O` above, we have to consider that other
@@ -874,19 +887,19 @@ struct OptionsParser
// just detect it as a prefix.
else if( argStr == "-g" || argStr == "-g2" )
{
- spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_STANDARD);
+ compileRequest->setDebugInfoLevel(SLANG_DEBUG_INFO_LEVEL_STANDARD);
}
else if( argStr == "-g0" )
{
- spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_NONE);
+ compileRequest->setDebugInfoLevel(SLANG_DEBUG_INFO_LEVEL_NONE);
}
else if( argStr == "-g1" )
{
- spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_MINIMAL);
+ compileRequest->setDebugInfoLevel(SLANG_DEBUG_INFO_LEVEL_MINIMAL);
}
else if( argStr == "-g3" )
{
- spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_MAXIMAL);
+ compileRequest->setDebugInfoLevel(SLANG_DEBUG_INFO_LEVEL_MAXIMAL);
}
else if( argStr == "-default-image-format-unknown" )
{
@@ -903,17 +916,17 @@ struct OptionsParser
if (name == "default")
{
- spSetFileSystem(compileRequest, nullptr);
+ compileRequest->setFileSystem(nullptr);
}
else if (name == "load-file")
{
// 'Simple' just implements loadFile interface, so will be wrapped with CacheFileSystem internally
- spSetFileSystem(compileRequest, OSFileSystem::getLoadSingleton());
+ compileRequest->setFileSystem(OSFileSystem::getLoadSingleton());
}
else if (name == "os")
{
// 'Immutable' implements the ISlangFileSystemExt interface - and will be used directly
- spSetFileSystem(compileRequest, OSFileSystem::getExtSingleton());
+ compileRequest->setFileSystem(OSFileSystem::getExtSingleton());
}
else
{
@@ -1019,7 +1032,7 @@ struct OptionsParser
return SLANG_OK;
}
- spSetCompileFlags(compileRequest, flags);
+ compileRequest->setCompileFlags(flags);
// As a compatability feature, if the user didn't list any explicit entry
// point names, *and* they are compiling a single translation unit, *and* they
@@ -1191,8 +1204,7 @@ struct OptionsParser
auto translationUnitID = rawTranslationUnits[rawEntryPoint.translationUnitIndex].translationUnitID;
- int entryPointID = spAddEntryPoint(
- compileRequest,
+ int entryPointID = compileRequest->addEntryPoint(
translationUnitID,
rawEntryPoint.name.begin(),
SlangStage(rawEntryPoint.stage));
@@ -1393,28 +1405,28 @@ struct OptionsParser
//
for(auto& rawTarget : rawTargets)
{
- int targetID = spAddCodeGenTarget(compileRequest, SlangCompileTarget(rawTarget.format));
+ int targetID = compileRequest->addCodeGenTarget(SlangCompileTarget(rawTarget.format));
rawTarget.targetID = targetID;
if( rawTarget.profileVersion != ProfileVersion::Unknown )
{
- spSetTargetProfile(compileRequest, targetID, Profile(rawTarget.profileVersion).raw);
+ compileRequest->setTargetProfile(targetID, Profile(rawTarget.profileVersion).raw);
}
if( rawTarget.targetFlags )
{
- spSetTargetFlags(compileRequest, targetID, rawTarget.targetFlags);
+ compileRequest->setTargetFlags(targetID, rawTarget.targetFlags);
}
if( rawTarget.floatingPointMode != FloatingPointMode::Default )
{
- spSetTargetFloatingPointMode(compileRequest, targetID, SlangFloatingPointMode(rawTarget.floatingPointMode));
+ compileRequest->setTargetFloatingPointMode(targetID, SlangFloatingPointMode(rawTarget.floatingPointMode));
}
}
if(defaultMatrixLayoutMode != SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)
{
- spSetMatrixLayoutMode(compileRequest, defaultMatrixLayoutMode);
+ compileRequest->setMatrixLayoutMode(defaultMatrixLayoutMode);
}
// Next we need to sort out the output files specified with `-o`, and
diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp
index 14e341bbc..e47fade70 100644
--- a/source/slang/slang-repro.cpp
+++ b/source/slang/slang-repro.cpp
@@ -881,13 +881,13 @@ struct LoadContext
// Try to set state through API - as doing so means if state stored in multiple places it will be ok
{
- spSetCompileFlags(externalRequest, (SlangCompileFlags)requestState->compileFlags);
- spSetDumpIntermediates(externalRequest, int(requestState->shouldDumpIntermediates));
- spSetLineDirectiveMode(externalRequest, SlangLineDirectiveMode(requestState->lineDirectiveMode));
- spSetDebugInfoLevel(externalRequest, SlangDebugInfoLevel(requestState->debugInfoLevel));
- spSetOptimizationLevel(externalRequest, SlangOptimizationLevel(requestState->optimizationLevel));
- spSetOutputContainerFormat(externalRequest, SlangContainerFormat(requestState->containerFormat));
- spSetPassThrough(externalRequest, SlangPassThrough(request->m_passThrough));
+ externalRequest->setCompileFlags((SlangCompileFlags)requestState->compileFlags);
+ externalRequest->setDumpIntermediates(int(requestState->shouldDumpIntermediates));
+ externalRequest->setLineDirectiveMode(SlangLineDirectiveMode(requestState->lineDirectiveMode));
+ externalRequest->setDebugInfoLevel(SlangDebugInfoLevel(requestState->debugInfoLevel));
+ externalRequest->setOptimizationLevel(SlangOptimizationLevel(requestState->optimizationLevel));
+ externalRequest->setOutputContainerFormat(SlangContainerFormat(requestState->containerFormat));
+ externalRequest->setPassThrough(SlangPassThrough(request->m_passThrough));
request->getBackEndReq()->useUnknownImageFormatAsDefault = requestState->useUnknownImageFormatAsDefault;
linkage->m_obfuscateCode = requestState->obfuscateCode;
@@ -900,7 +900,7 @@ struct LoadContext
for (Index i = 0; i < requestState->targetRequests.getCount(); ++i)
{
TargetRequestState& src = base.asRaw(requestState->targetRequests[i]);
- int index = spAddCodeGenTarget(externalRequest, SlangCompileTarget(src.target));
+ int index = externalRequest->addCodeGenTarget(SlangCompileTarget(src.target));
SLANG_ASSERT(index == i);
auto dstTarget = linkage->targets[index];
@@ -1005,7 +1005,7 @@ struct LoadContext
List<const char*> args = context.toList(srcEntryPoint.specializationArgStrings);
- spAddEntryPointEx(externalRequest, int(srcEntryPoint.translationUnitIndex), name, SlangStage(stage), int(args.getCount()), args.getBuffer());
+ externalRequest->addEntryPointEx(int(srcEntryPoint.translationUnitIndex), name, SlangStage(stage), int(args.getCount()), args.getBuffer());
}
}
@@ -1372,10 +1372,9 @@ static SlangResult _calcCommandLine(OffsetBase& base, ReproUtil::RequestState* r
//cmd.addArg("-profile");
//cmd.addArg(Profile(srcEntryPoint.profile).getName());
-
//List<const char*> args = context.toList(srcEntryPoint.specializationArgStrings);
- //spAddEntryPointEx(externalRequest, int(srcEntryPoint.translationUnitIndex), name, SlangStage(stage), int(args.getCount()), args.getBuffer());
+ //externalRequest->addEntryPointEx(int(srcEntryPoint.translationUnitIndex), name, SlangStage(stage), int(args.getCount()), args.getBuffer());
}
}
diff --git a/source/slang/slang-stdlib-api.cpp b/source/slang/slang-stdlib-api.cpp
new file mode 100644
index 000000000..e5934531a
--- /dev/null
+++ b/source/slang/slang-stdlib-api.cpp
@@ -0,0 +1,29 @@
+// slang-stdlib-api.cpp
+
+#include "../core/slang-basic.h"
+#include "../core/slang-array-view.h"
+
+#include "../core/slang-blob.h"
+
+#ifdef SLANG_WITHOUT_EMBEDDED_STD_LIB
+
+SLANG_API ISlangBlob* slang_getEmbeddedStdLib()
+{
+ return nullptr;
+}
+
+#else
+
+static const uint8_t g_stdLib[] =
+{
+# include "slang-stdlib-generated.h"
+};
+
+static Slang::StaticBlob g_stdLibBlob((const void*)g_stdLib, sizeof(g_stdLib));
+
+SLANG_API ISlangBlob* slang_getEmbeddedStdLib()
+{
+ return &g_stdLibBlob;
+}
+
+#endif
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 4a25c2392..92a08a224 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -4,6 +4,8 @@
#include "../core/slang-string-util.h"
#include "../core/slang-shared-library.h"
+#include "../core/slang-zip-file-system.h"
+
#include "slang-check.h"
#include "slang-parameter-binding.h"
#include "slang-lower-to-ir.h"
@@ -31,6 +33,8 @@
#include "slang-check-impl.h"
+#include "../../slang-tag-version.h"
+
// Used to print exception type names in internal-compiler-error messages
#include <typeinfo>
@@ -117,6 +121,11 @@ static const Guid IID_ICompileRequest = SLANG_UUID_ICompileRequest;
// Available to other modules so not static
const Guid IID_EndToEndCompileRequest = SLANG_UUID_EndToEndCompileRequest;
+const char* getBuildTagString()
+{
+ return SLANG_TAG_VERSION;
+}
+
void Session::init()
{
SLANG_ASSERT(BaseTypeInfo::check());
@@ -248,7 +257,7 @@ SlangResult Session::compileStdLib()
return SLANG_OK;
}
-SlangResult Session::loadStdLib()
+SlangResult Session::loadStdLib(const void* stdLib, size_t stdLibSizeInBytes)
{
if (m_builtinLinkage->mapNameToLoadedModules.Count())
{
@@ -256,13 +265,17 @@ SlangResult Session::loadStdLib()
return SLANG_FAIL;
}
+ // Make a file system to read it from
+ RefPtr<CompressedFileSystem> fileSystem;
+ SLANG_RETURN_ON_FAIL(CompressedFileSystem::createZip(stdLib, stdLibSizeInBytes, fileSystem));
+
// Let's try loading serialized modules and adding them
- SLANG_RETURN_ON_FAIL(_readBuiltinModule(coreLanguageScope, "core"));
- SLANG_RETURN_ON_FAIL(_readBuiltinModule(hlslLanguageScope, "hlsl"));
+ SLANG_RETURN_ON_FAIL(_readBuiltinModule(fileSystem, coreLanguageScope, "core"));
+ SLANG_RETURN_ON_FAIL(_readBuiltinModule(fileSystem, hlslLanguageScope, "hlsl"));
return SLANG_OK;
}
-SlangResult Session::saveStdLib()
+SlangResult Session::saveStdLib(ISlangBlob** outBlob)
{
if (m_builtinLinkage->mapNameToLoadedModules.Count() == 0)
{
@@ -270,6 +283,10 @@ SlangResult Session::saveStdLib()
return SLANG_FAIL;
}
+ // Make a file system to read it from
+ RefPtr<CompressedFileSystem> fileSystem;
+ SLANG_RETURN_ON_FAIL(CompressedFileSystem::createZip(fileSystem));
+
for (auto& pair : m_builtinLinkage->mapNameToLoadedModules)
{
const Name* moduleName = pair.Key;
@@ -287,30 +304,44 @@ SlangResult Session::saveStdLib()
StringBuilder builder;
builder << moduleName->text << ".slang-module";
- FileStream stream(builder.ProduceString(), FileMode::Create, FileAccess::Write, FileShare::ReadWrite);
+ OwnedMemoryStream stream(FileAccess::Write);
+
SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(module, options, &stream));
+
+ auto contents = stream.getContents();
+
+ // Write into the file system
+ SLANG_RETURN_ON_FAIL(fileSystem->saveFile(builder.getBuffer(), contents.getBuffer(), contents.getCount()));
}
+ // Now need to convert into a blob
+ auto archiveContents = fileSystem->getArchive();
+
+ ComPtr<ISlangBlob> blob(new RawBlob(archiveContents.getBuffer(), archiveContents.getCount()));
+ *outBlob = blob.detach();
+
return SLANG_OK;
}
-SlangResult Session::_readBuiltinModule(Scope* scope, String moduleName)
+SlangResult Session::_readBuiltinModule(ISlangFileSystem* fileSystem, Scope* scope, String moduleName)
{
+ // Get the name of the module
StringBuilder moduleFilename;
moduleFilename << moduleName << ".slang-module";
RiffContainer riffContainer;
- try
{
- FileStream stream(moduleFilename.ProduceString(), FileMode::Open, FileAccess::Read, FileShare::ReadOnly);
+ // Load it
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(fileSystem->loadFile(moduleFilename.getBuffer(), blob.writeRef()));
+
+ // Set up a stream
+ MemoryStreamBase stream(FileAccess::Read, blob->getBufferPointer(), blob->getBufferSize());
+
// Load the riff container
SLANG_RETURN_ON_FAIL(RiffUtil::read(&stream, riffContainer));
}
- catch (const IOException&)
- {
- return SLANG_FAIL;
- }
-
+
// Load up the module
SerialContainerData containerData;
@@ -339,6 +370,8 @@ SlangResult Session::_readBuiltinModule(Scope* scope, String moduleName)
RefPtr<Module> module(new Module(linkage, srcModule.astBuilder));
ModuleDecl* moduleDecl = as<ModuleDecl>(srcModule.astRootNode);
+ // Set the module back reference on the decl
+ moduleDecl->module = module;
if (moduleDecl)
{
@@ -510,7 +543,7 @@ SLANG_NO_THROW void SLANG_MCALL Session::getLanguagePrelude(
SLANG_NO_THROW const char* SLANG_MCALL Session::getBuildTagString()
{
- return spGetBuildTagString();
+ return ::Slang::getBuildTagString();
}
SLANG_NO_THROW SlangResult SLANG_MCALL Session::setDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler)
diff --git a/tests/serialization/std-lib-serialize.slang b/tests/serialization/std-lib-serialize.slang
index e55a2cd69..6745b851a 100644
--- a/tests/serialization/std-lib-serialize.slang
+++ b/tests/serialization/std-lib-serialize.slang
@@ -1,5 +1,5 @@
-//TEST:COMPILE: -save-stdlib
-//TEST:COMPARE_COMPUTE: -compile-arg -load-stdlib
+//TEST:COMPILE: -save-stdlib slang-std-lib.zip
+//TEST:COMPARE_COMPUTE: -compile-arg -load-stdlib -compile-arg slang-std-lib.zip
struct A
{
diff --git a/tools/slang-test/unit-test-compression.cpp b/tools/slang-test/unit-test-compression.cpp
index 787c798b5..d9900bbfa 100644
--- a/tools/slang-test/unit-test-compression.cpp
+++ b/tools/slang-test/unit-test-compression.cpp
@@ -17,7 +17,7 @@ static bool _equals(const char (&text)[SIZE], ISlangBlob* blob)
return _equals(text, SIZE, blob);
}
-static List<String> _getContents(ISlangFileSystemExt* fileSystem, char* path)
+static List<String> _getContents(ISlangFileSystemExt* fileSystem, const char* path)
{
List<String> objs;