summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--premake5.lua12
-rw-r--r--slang.h34
-rw-r--r--slang.sln13
-rw-r--r--source/slang/bytecode.cpp1071
-rw-r--r--source/slang/bytecode.h253
-rw-r--r--source/slang/compiler.cpp13
-rw-r--r--source/slang/ir.cpp15
-rw-r--r--source/slang/slang.vcxproj4
-rw-r--r--source/slang/slang.vcxproj.filters14
-rw-r--r--source/slang/vm.cpp1180
-rw-r--r--source/slang/vm.h19
-rw-r--r--tools/slang-eval-test/main.cpp139
-rw-r--r--tools/slang-eval-test/slang-eval-test.vcxproj178
-rw-r--r--tools/slang-eval-test/slang-eval-test.vcxproj.filters13
-rw-r--r--tools/slang-test/main.cpp48
16 files changed, 19 insertions, 2999 deletions
diff --git a/Makefile b/Makefile
index bd9f1ddb0..bce0ab803 100644
--- a/Makefile
+++ b/Makefile
@@ -103,9 +103,6 @@ SLANGC_SOURCES += $(CORE_SOURCES)
SLANG_GLSLANG_SOURCES := source/slang-glslang/*.cpp
SLANG_GLSLANG_HEADERS := source/slang-glslang/*.h
-SLANG_EVAL_TEST_SOURCES := tools/slang-eval-test/*.cpp
-SLANG_EVAL_TEST_HEADERS :=
-
SLANG_REFLECTION_TEST_SOURCES := tools/slang-reflection-test/*.cpp
SLANG_REFLECTION_TEST_HEADERS :=
@@ -137,12 +134,11 @@ SLANG := $(OUTPUTDIR)$(SHARED_LIB_PREFIX)slang$(SHARED_LIB_SUFFIX)
SLANGC := $(OUTPUTDIR)slangc$(BIN_SUFFIX)
SLANG_GLSLANG := $(OUTPUTDIR)$(SHARED_LIB_PREFIX)slang-glslang$(SHARED_LIB_SUFFIX)
SLANG_TEST := $(OUTPUTDIR)slang-test$(BIN_SUFFIX)
-SLANG_EVAL_TEST := $(OUTPUTDIR)slang-eval-test$(BIN_SUFFIX)
SLANG_REFLECTION_TEST := $(OUTPUTDIR)slang-reflection-test$(BIN_SUFFIX)
# By default, when the user invokes `make`, we will build the
# `slang` shared library, and the `slangc` front-end application.
-all: slang slang-glslang slangc slang-test slang-eval-test slang-reflection-test
+all: slang slang-glslang slangc slang-test slang-reflection-test
mkdirs: $(OUTPUTDIR)
@@ -151,7 +147,6 @@ slang: mkdirs $(SLANG)
slangc: mkdirs $(SLANGC)
slang-glslang: mkdirs $(SLANG_GLSLANG)
slang-test: mkdirs $(SLANG_TEST)
-slang-eval-test: mkdirs $(SLANG_EVAL_TEST)
slang-reflection-test: mkdirs $(SLANG_REFLECTION_TEST)
$(SLANG): $(SLANG_SOURCES) $(SLANG_HEADERS)
@@ -166,16 +161,13 @@ $(SLANG_GLSLANG): $(SLANG_GLSLANG_SOURCES) $(SLANG_GLSLANG_HEADERS)
$(SLANG_TEST): $(SLANG_TEST_SOURCES) $(SLANG_TEST_HEADERS) $(SLANG)
$(CXX) $(LDFLAGS) -o $@ $(CFLAGS) $(SLANG_TEST_SOURCES) -ldl $(RELATIVE_RPATH_INCANTATION) -lslang
-$(SLANG_EVAL_TEST): $(SLANG_EVAL_TEST_SOURCES) $(SLANG)
- $(CXX) $(LDFLAGS) -o $@ $(CFLAGS) $(SLANG_EVAL_TEST_SOURCES) $(RELATIVE_RPATH_INCANTATION) -lslang
-
$(SLANG_REFLECTION_TEST): $(SLANG_REFLECTION_TEST_SOURCES) $(SLANG)
$(CXX) $(LDFLAGS) -o $@ $(CFLAGS) $(SLANG_REFLECTION_TEST_SOURCES) $(RELATIVE_RPATH_INCANTATION) -lslang
$(OUTPUTDIR):
mkdir -p $(OUTPUTDIR)
-test: $(SLANG_TEST) $(SLANG_EVAL_TEST) $(SLANG_REFLECTION_TEST)
+test: $(SLANG_TEST) $(SLANG_REFLECTION_TEST)
$(SLANG_TEST) -bindir $(OUTPUTDIR) -travis -category $(SLANG_TEST_CATEGORY) $(SLANG_TEST_FLAGS)
clean:
diff --git a/premake5.lua b/premake5.lua
index dcc86913a..7bf5a34ca 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -449,18 +449,6 @@ tool "slang-reflection-test"
links { "slang" }
--
--- `slang-eval-test` is similarly easy to build:
---
--- Note: `slang-eval-test` will probably be deprecated and its functionality
--- folded into `render-test`, but we aren't ready for that just yet.
---
-
-tool "slang-eval-test"
- uuid "205FCAB9-A13F-4980-86FA-F6221A7095EE"
- includedirs { "." }
- links { "core", "slang" }
-
---
-- The most complex testing tool we have is `render-test`, but from
-- a build perspective the most interesting thing about it is that for
-- our Windows build it requires a Windows 10 SDK.
diff --git a/slang.h b/slang.h
index ed0fb32a4..8085bf15c 100644
--- a/slang.h
+++ b/slang.h
@@ -1237,40 +1237,6 @@ extern "C"
SlangCompileRequest* request,
size_t* outSize);
-
-
- typedef struct SlangVM SlangVM;
- typedef struct SlangVMModule SlangVMModule;
- typedef struct SlangVMFunc SlangVMFunc;
- typedef struct SlangVMThread SlangVMThread;
-
- SLANG_API SlangVM* SlangVM_create();
-
- SLANG_API SlangVMModule* SlangVMModule_load(
- SlangVM* vm,
- void const* bytecode,
- size_t bytecodeSize);
-
- SLANG_API void* SlangVMModule_findGlobalSymbolPtr(
- SlangVMModule* module,
- char const* name);
-
- SLANG_API SlangVMThread* SlangVMThread_create(
- SlangVM* vm);
-
- SLANG_API void SlangVMThread_beginCall(
- SlangVMThread* thread,
- SlangVMFunc* func);
-
- SLANG_API void SlangVMThread_setArg(
- SlangVMThread* thread,
- SlangUInt argIndex,
- void const* data,
- size_t size);
-
- SLANG_API void SlangVMThread_resume(
- SlangVMThread* thread);
-
/* Note(tfoley): working on new reflection interface...
*/
diff --git a/slang.sln b/slang.sln
index 8adbb3822..1556f1963 100644
--- a/slang.sln
+++ b/slang.sln
@@ -1,6 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello-world", "examples\hello-world\hello-world.vcxproj", "{5CF41E7B-4883-A844-F1A1-BC3FDD0FB9EA}"
@@ -17,8 +19,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-test", "tools\slang-t
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-reflection-test", "tools\slang-reflection-test\slang-reflection-test.vcxproj", "{22C45F4F-FB6B-4535-BED1-D3F5D0C71047}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-eval-test", "tools\slang-eval-test\slang-eval-test.vcxproj", "{205FCAB9-A13F-4980-86FA-F6221A7095EE}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "render-test", "tools\render-test\render-test.vcxproj", "{96610759-07B9-4EEB-A974-5C634A2E742B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gfx", "tools\gfx\gfx.vcxproj", "{222F7498-B40C-4F3F-A704-DDEB91A4484A}"
@@ -88,14 +88,6 @@ Global
{22C45F4F-FB6B-4535-BED1-D3F5D0C71047}.Release|Win32.Build.0 = Release|Win32
{22C45F4F-FB6B-4535-BED1-D3F5D0C71047}.Release|x64.ActiveCfg = Release|x64
{22C45F4F-FB6B-4535-BED1-D3F5D0C71047}.Release|x64.Build.0 = Release|x64
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Debug|Win32.ActiveCfg = Debug|Win32
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Debug|Win32.Build.0 = Debug|Win32
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Debug|x64.ActiveCfg = Debug|x64
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Debug|x64.Build.0 = Debug|x64
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Release|Win32.ActiveCfg = Release|Win32
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Release|Win32.Build.0 = Release|Win32
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Release|x64.ActiveCfg = Release|x64
- {205FCAB9-A13F-4980-86FA-F6221A7095EE}.Release|x64.Build.0 = Release|x64
{96610759-07B9-4EEB-A974-5C634A2E742B}.Debug|Win32.ActiveCfg = Debug|Win32
{96610759-07B9-4EEB-A974-5C634A2E742B}.Debug|Win32.Build.0 = Debug|Win32
{96610759-07B9-4EEB-A974-5C634A2E742B}.Debug|x64.ActiveCfg = Debug|x64
@@ -146,7 +138,6 @@ Global
{66174227-8541-41FC-A6DF-4764FC66F78E} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13}
{0C768A18-1D25-4000-9F37-DA5FE99E3B64} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13}
{22C45F4F-FB6B-4535-BED1-D3F5D0C71047} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13}
- {205FCAB9-A13F-4980-86FA-F6221A7095EE} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13}
{96610759-07B9-4EEB-A974-5C634A2E742B} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13}
{222F7498-B40C-4F3F-A704-DDEB91A4484A} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13}
EndGlobalSection
diff --git a/source/slang/bytecode.cpp b/source/slang/bytecode.cpp
deleted file mode 100644
index 7ceb06cdc..000000000
--- a/source/slang/bytecode.cpp
+++ /dev/null
@@ -1,1071 +0,0 @@
-#include "bytecode.h"
-
-// Implementation of the Slang bytecode (BC)
-// (most notably including conversion from IR to BC)
-
-#include "compiler.h"
-#include "ir.h"
-#include "ir-insts.h"
-#include "lower-to-ir.h"
-
-namespace Slang
-{
-struct SharedBytecodeGenerationContext;
-
-// Representation of a `BCPtr<T>` during actual bytecode generation.
-// This representation is to deal with the fact that the actual
-// storage for the bytecode data might get reallocated during emission
-// so that we need to be careful and not work with raw `BCPtr<T>`.
-template<typename T>
-struct BytecodeGenerationPtr
-{
- UInt offset;
- SharedBytecodeGenerationContext* sharedContext;
-
- BytecodeGenerationPtr()
- : sharedContext(nullptr)
- , offset(0)
- {}
-
-
- BytecodeGenerationPtr(
- SharedBytecodeGenerationContext* sharedContext,
- UInt offset)
- : sharedContext(sharedContext)
- , offset(offset)
- {}
-
- BytecodeGenerationPtr(
- BytecodeGenerationPtr<T> const& ptr)
- : sharedContext(ptr.sharedContext)
- , offset(ptr.offset)
- {}
-
- template<typename U>
- BytecodeGenerationPtr(
- BytecodeGenerationPtr<U> const& ptr,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
- : sharedContext(ptr.sharedContext)
- , offset(ptr.offset)
- {}
-
- template<typename U>
- BytecodeGenerationPtr<U> bitCast() const
- {
- return BytecodeGenerationPtr<U>(sharedContext, offset);
- }
-
- operator BCPtr<T>() const
- {
- return BCPtr<T>(getPtr());
- }
-
- T* operator->() const
- {
- return getPtr();
- }
-
- T& operator*() const
- {
- return *getPtr();
- }
-
- T& operator[](UInt index) const
- {
- return getPtr()[index];
- }
-
- BytecodeGenerationPtr<T> operator+(Int index) const
- {
- Int delta = index * sizeof(T);
- UInt newOffset = offset + delta;
- return BytecodeGenerationPtr<T>(
- sharedContext,
- newOffset);
- }
-
- T* getPtr() const;
-};
-
-#if 0
-template<typename T>
-void BCPtr<T>::operator=(BytecodeGenerationPtr<T> const& ptr)
-{
- fprintf(stderr, "0x%p: operator=BGP 0x%p\n", this, ptr.getPtr());
- *this = ptr.getPtr();
-}
-#endif
-
-struct SharedBytecodeGenerationContext
-{
- // The final generated bytecode stream
- List<uint8_t> bytecode;
-
- // Map from an IR value to a global entity
- // that encodes it:
- Dictionary<IRInst*, BCConst> mapValueToGlobal;
-
- // Types that have been emitted
- List<BytecodeGenerationPtr<BCType>> bcTypes;
- Dictionary<IRType*, UInt> mapTypeToID;
-
- // Compile-time constant values that need
- // to be emitted...
- List<IRInst*> constants;
-};
-
-struct BytecodeGenerationContext
-{
- SharedBytecodeGenerationContext* shared;
-
- // The bytecode of the current symbol being
- // output.
- List<uint8_t> currentBytecode;
-
- // The function that is in scope for this context
- IRFunc* currentIRFunc;
-
- // Counter for global symbols that have been assigned
- // so that they can be used by this function
- List<BCConst> remappedGlobalSymbols;
-
- // Map an instruction to its ID for use local
- // to the current context
- Dictionary<IRInst*, Int> mapInstToLocalID;
-};
-
-template<typename T>
-T* BytecodeGenerationPtr<T>::getPtr() const
-{
- if(!sharedContext) return nullptr;
- return (T*)(sharedContext->bytecode.Buffer() + offset);
-}
-
-
-BCPtr<void>::RawVal allocateRaw(
- BytecodeGenerationContext* context,
- size_t size,
- size_t alignment)
-{
- size_t currentOffset = context->shared->bytecode.Count();
-
- size_t beginOffset = (currentOffset + (alignment-1)) & ~(alignment-1);
-
- size_t endOffset = beginOffset + size;
-
- for(size_t ii = currentOffset; ii < endOffset; ++ii)
- context->shared->bytecode.Add(0);
-
- return (BCPtr<void>::RawVal)beginOffset;
-}
-
-template<typename T>
-BytecodeGenerationPtr<T> allocate(
- BytecodeGenerationContext* context)
-{
- return BytecodeGenerationPtr<T>(context->shared, allocateRaw(context, sizeof(T), alignof(T)));
-}
-
-template<typename T>
-BytecodeGenerationPtr<T> allocateArray(
- BytecodeGenerationContext* context,
- UInt count)
-{
- return BytecodeGenerationPtr<T>(context->shared, allocateRaw(context, count * sizeof(T), alignof(T)));
-}
-
-template<typename T>
-BytecodeGenerationPtr<T> getPtr(
- BytecodeGenerationContext* context)
-{
- return BytecodeGenerationPtr<T>(context->shared, context->shared->bytecode.Count());
-}
-
-
-void encodeUInt8(
- BytecodeGenerationContext* context,
- uint8_t value)
-{
- context->currentBytecode.Add(value);
-}
-
-void encodeUInt(
- BytecodeGenerationContext* context,
- UInt value)
-{
- if( value < 128 )
- {
- encodeUInt8(context, (uint8_t)value);
- return;
- }
-
- uint8_t bytes[16];
- UInt count = 0;
-
- for(;;)
- {
- UInt index = count++;
- bytes[index] = value & 0x7F;
- value = value >> 7;
- if (!value)
- break;
-
- bytes[index] |= 0x80;
- }
-
- UInt index = count;
- while (index--)
- {
- encodeUInt8(context, bytes[index]);
- }
-}
-
-void encodeSInt(
- BytecodeGenerationContext* context,
- Int value)
-{
- UInt uValue;
- if( value < 0 )
- {
- uValue = (~UInt(value) << 1) | 1;
- }
- else
- {
- uValue = UInt(value) << 1;
- }
-
- encodeUInt(context, uValue);
-}
-
-BCConst getGlobalValue(
- BytecodeGenerationContext* context,
- IRInst* value)
-{
- {
- BCConst bcConst;
- if (context->shared->mapValueToGlobal.TryGetValue(value, bcConst))
- return bcConst;
- }
- // Next we need to check for things that can be mapped to
- // global IDs on the fly.
-
- switch( value->op )
- {
- case kIROp_IntLit:
- {
- UInt constID = context->shared->constants.Count();
- context->shared->constants.Add(value);
-
- BCConst bcConst;
- bcConst.flavor = kBCConstFlavor_Constant;
- bcConst.id = (uint32_t)constID;
-
- context->shared->mapValueToGlobal.Add(value, bcConst);
-
- return bcConst;
- }
- break;
-
- default:
- break;
- }
-
- SLANG_UNEXPECTED("no ID for inst");
- {
- UNREACHABLE(BCConst bcConst);
- UNREACHABLE(bcConst.flavor = (BCConstFlavor)-1);
- UNREACHABLE(bcConst.id = -9999);
- UNREACHABLE_RETURN(bcConst);
- }
-}
-
-Int getLocalID(
- BytecodeGenerationContext* context,
- IRInst* value)
-{
- Int localID = 0;
- if( context->mapInstToLocalID.TryGetValue(value, localID) )
- {
- return localID;
- }
-
- BCConst bcConst = getGlobalValue(context, value);
- UInt remappedSymbolIndex = context->remappedGlobalSymbols.Count();
- context->remappedGlobalSymbols.Add(bcConst);
-
- localID = ~remappedSymbolIndex;
- context->mapInstToLocalID.Add(value, localID);
- return localID;
-}
-
-void encodeOperand(
- BytecodeGenerationContext* context,
- IRInst* operand)
-{
- auto id = getLocalID(context, operand);
- encodeSInt(context, id);
-}
-
-uint32_t getTypeID(
- BytecodeGenerationContext* context,
- IRType* type);
-
-void encodeOperand(
- BytecodeGenerationContext* context,
- IRType* type)
-{
- encodeUInt(context, getTypeID(context, type));
-}
-
-bool opHasResult(IRInst* inst)
-{
- auto type = inst->getDataType();
- if (!type) return false;
-
- // As a bit of a hack right now, we need to check whether
- // the function returns the distinguished `Void` type,
- // since that is conceptually the same as "not returning
- // a value."
- if(type->op == kIROp_VoidType)
- return false;
-
- return true;
-}
-
-void generateBytecodeForInst(
- BytecodeGenerationContext* context,
- IRInst* inst)
-{
- // We are generating bytecode for a local instruction
- // inside a function or similar context.
- switch( inst->op )
- {
- default:
- {
- // As a default case, we will assume that bytecode ops
- // and the IR's internal opcodes are the same, and then
- // encode the necessary extra info:
- //
-
- auto operandCount = inst->getOperandCount();
- encodeUInt(context, inst->op);
- encodeOperand(context, inst->getDataType());
- encodeUInt(context, operandCount);
- for( UInt aa = 0; aa < operandCount; ++aa )
- {
- encodeOperand(context, inst->getOperand(aa));
- }
-
- if (!opHasResult(inst))
- {
- // This instructions has no type, so don't emit a destination
- }
- else
- {
- // The instruction can be encoded
- // as its own operand for the destination.
- encodeOperand(context, inst);
- }
- }
- break;
-
- case kIROp_ReturnVoid:
- // Trivial encoding here
- encodeUInt(context, inst->op);
- break;
-
- case kIROp_IntLit:
- {
- auto ii = (IRConstant*) inst;
- encodeUInt(context, ii->op);
- encodeOperand(context, ii->getDataType());
-
- // TODO: probably want distinct encodings
- // for signed vs. unsigned here.
- encodeUInt(context, UInt(ii->value.intVal));
-
- // destination:
- encodeOperand(context, inst);
- }
- break;
-
- case kIROp_FloatLit:
- {
- auto cInst = (IRConstant*) inst;
- encodeUInt(context, cInst->op);
- encodeOperand(context, cInst->getDataType());
-
- static const UInt size = sizeof(IRFloatingPointValue);
- unsigned char buffer[size];
- memcpy(buffer, &cInst->value.floatVal, sizeof(buffer));
-
- for(UInt ii = 0; ii < size; ++ii)
- {
- encodeUInt8(context, buffer[ii]);
- }
-
- // destination:
- encodeOperand(context, inst);
- }
- break;
-
- case kIROp_BoolLit:
- {
- auto ii = (IRConstant*) inst;
- encodeUInt(context, ii->op);
- encodeUInt(context, ii->value.intVal ? 1 : 0);
-
- // destination:
- encodeOperand(context, inst);
- }
- break;
-
-#if 0
- case kIROp_Func:
- {
- encodeUInt(context, inst->op);
-
- // We just want to encode the ID for the function
- // symbol data, and then do the rest on the decode side
- UInt nestedID = 0;
- context->mapInstToNestedID.TryGetValue(inst, nestedID);
- encodeUInt(context, nestedID);
-
- // destination:
- encodeOperand(context, inst);
- }
- break;
-#endif
-
- case kIROp_Store:
- {
- encodeUInt(context, inst->op);
-
- // We need to encode the type being stored, to make
- // our lives easier.
- encodeOperand(context, inst->getOperand(1)->getDataType());
- encodeOperand(context, inst->getOperand(0));
- encodeOperand(context, inst->getOperand(1));
- }
- break;
-
- case kIROp_Load:
- {
- encodeUInt(context, inst->op);
- encodeOperand(context, inst->getDataType());
- encodeOperand(context, inst->getOperand(0));
- encodeOperand(context, inst);
- }
- break;
- }
-}
-
-BytecodeGenerationPtr<BCType> emitBCType(
- BytecodeGenerationContext* context,
- IRType* type,
- IROp op,
- BytecodeGenerationPtr<uint8_t> const* args,
- UInt argCount)
-{
- UInt size = sizeof(BCType)
- + argCount * sizeof(BCPtr<void>);
-
- BytecodeGenerationPtr<uint8_t> bcAllocation(
- context->shared,
- allocateRaw(context, size, alignof(BCPtr<void>)));
-
- BytecodeGenerationPtr<BCType> bcType = bcAllocation.bitCast<BCType>();
- auto bcArgs = (bcType + 1).bitCast<BCPtr<uint8_t>>();
-
- bcType->op = op;
- bcType->argCount = (uint32_t)argCount;
-
- for(UInt aa = 0; aa < argCount; ++aa)
- {
- bcArgs[aa] = args[aa];
- }
-
- UInt id = context->shared->bcTypes.Count();
- context->shared->mapTypeToID.Add(type, id);
- context->shared->bcTypes.Add(bcType);
- bcType->id = (uint32_t)id;
-
- return bcType;
-}
-
-BytecodeGenerationPtr<BCType> emitBCVarArgType(
- BytecodeGenerationContext* context,
- IRType* type,
- IROp op,
- List<BytecodeGenerationPtr<uint8_t>> args)
-{
- return emitBCType(context, type, op, args.Buffer(), args.Count());
-}
-
-BytecodeGenerationPtr<BCType> emitBCType(
- BytecodeGenerationContext* context,
- IRType* type,
- IROp op)
-{
- return emitBCType(context, type, op, nullptr, 0);
-}
-
-BytecodeGenerationPtr<BCType> emitBCType(
- BytecodeGenerationContext* context,
- IRType* type);
-
-// Emit a `BCType` representation for the given `Type`
-BytecodeGenerationPtr<BCType> emitBCTypeImpl(
- BytecodeGenerationContext* context,
- IRType* type)
-{
- // A NULL type is interpreted as equivalent to `Void` for now.
- if( !type )
- {
- return emitBCType(context, type, kIROp_VoidType);
- }
-
- List<BytecodeGenerationPtr<uint8_t>> operands;
- UInt operandCount = type->getOperandCount();
- for (UInt ii = 0; ii < operandCount; ++ii)
- {
- operands.Add(emitBCType(context, (IRType*) type->getOperand(ii)).bitCast<uint8_t>());
- }
- return emitBCVarArgType(context, type, type->op, operands);
-}
-
-BytecodeGenerationPtr<BCType> emitBCType(
- BytecodeGenerationContext* context,
- IRType* type)
-{
- auto canonical = type->getCanonicalType();
- UInt id = 0;
- if(context->shared->mapTypeToID.TryGetValue(canonical, id))
- {
- return context->shared->bcTypes[id];
- }
-
- BytecodeGenerationPtr<BCType> bcType = emitBCTypeImpl(context, canonical);
- return bcType;
-}
-
-uint32_t getTypeID(
- BytecodeGenerationContext* context,
- IRType* type)
-{
- // We have a type, and we need to emit it (if we haven't
- // already) and return its index in the global type table.
- BytecodeGenerationPtr<BCType> bcType = emitBCType(context, type);
- return bcType->id;
-}
-
-uint32_t getTypeIDForGlobalSymbol(
- BytecodeGenerationContext* context,
- IRInst* inst)
-{
- auto type = inst->getDataType();
- if(!type)
- return 0;
-
- return getTypeID(context, type);
-}
-
-BytecodeGenerationPtr<char> allocateString(
- BytecodeGenerationContext* context,
- char const* data,
- UInt size)
-{
- BytecodeGenerationPtr<char> ptr = allocateArray<char>(context, size + 1);
- memcpy(ptr.getPtr(), data, size);
- return ptr;
-}
-
-BytecodeGenerationPtr<char> allocateString(
- BytecodeGenerationContext* context,
- String const& str)
-{
- return allocateString(context,
- str.Buffer(),
- str.Length());
-}
-
-BytecodeGenerationPtr<char> allocateString(
- BytecodeGenerationContext* context,
- Name* name)
-{
- return allocateString(context, name->text);
-}
-
-BytecodeGenerationPtr<char> tryGenerateNameForSymbol(
- BytecodeGenerationContext* context,
- IRGlobalValue* inst)
-{
- // TODO: this is gross, and the IR should probably have
- // a more direct means of querying a name for a symbol.
- if (auto highLevelDeclDecoration = inst->findDecoration<IRHighLevelDeclDecoration>())
- {
- auto decl = highLevelDeclDecoration->decl;
- if (auto reflectionNameMod = decl->FindModifier<ParameterGroupReflectionName>())
- {
- return allocateString(context, reflectionNameMod->name);
- }
- else if(auto name = decl->nameAndLoc.name)
- {
- return allocateString(context, name);
- }
- }
-
- return BytecodeGenerationPtr<char>();
-}
-
-// Generate a `BCSymbol` that can represent a global value.
-BytecodeGenerationPtr<BCSymbol> generateBytecodeSymbolForInst(
- BytecodeGenerationContext* context,
- IRGlobalValue* inst)
-{
- switch( inst->op )
- {
- case kIROp_Func:
- {
- auto irFunc = (IRFunc*) inst;
- BytecodeGenerationPtr<BCFunc> bcFunc = allocate<BCFunc>(context);
-
- bcFunc->op = inst->op;
- bcFunc->typeID = getTypeIDForGlobalSymbol(context, inst);
-
- BytecodeGenerationContext subContextStorage;
- BytecodeGenerationContext* subContext = &subContextStorage;
- subContext->shared = context->shared;
- subContext->currentIRFunc = irFunc;
-
- // First we need to enumerate our basic blocks, so that they
- // can reference one another (basic blocks can forward reference
- // blocks that haven't been seen yet).
- //
- // Note: we allow the IDs of blocks to overlap with ordinary
- // "register" numbers, because there is no case where an operand
- // could be either a block or an ordinary register.
- //
- UInt blockCounter = 0;
- for( auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock() )
- {
- Int blockID = Int(blockCounter++);
- subContext->mapInstToLocalID.Add(bb, blockID);
- }
- UInt blockCount = blockCounter;
-
- // Allocate the array of block objects to be stored in the
- // bytecode file.
- auto bcBlocks = allocateArray<BCBlock>(context, blockCount);
- bcFunc->blockCount = (uint32_t)blockCount;
- bcFunc->blocks = bcBlocks;
-
- // Now loop through the blocks again, and allocate the storage
- // for any parameters, variables, or registers used inside
- // each block.
- //
- // We'll count in a first pass, and then fill things in
- // using a second pass
- Int regCounter = 0;
- blockCounter = 0;
- for( auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock() )
- {
- UInt blockID = blockCounter++;
- UInt paramCount = 0;
-
- for( auto ii = bb->getFirstInst(); ii; ii = ii->getNextInst() )
- {
- switch( ii->op )
- {
- default:
- // Default behavior: if an op has a result,
- // then it needs a register to store it.
- if(opHasResult(ii))
- {
- regCounter++;
- }
- break;
-
- case kIROp_Param:
- // A parameter always uses a register.
- regCounter++;
- //
- // We also want to keep a count of the parameters themselves.
- paramCount++;
- break;
-
- case kIROp_Var:
- // A `var` (`alloca`) node needs two registers:
- // one to hold the actual storage, and another
- // to hold the pointer.
- regCounter += 2;
- break;
- }
- }
-
- bcBlocks[blockID].paramCount = (uint32_t)paramCount;
- }
-
- // Okay, we've counted how many registers we need for each block,
- // and now we can allocate the contiguous array we will use.
- UInt regCount = regCounter;
- auto bcRegs = allocateArray<BCReg>(context, regCount);
-
- bcFunc->regCount = (uint32_t)regCount;
- bcFunc->regs = bcRegs;
-
- // Now we will loop over things again to fill in the information
- // on all these registers.
-
- regCounter = 0;
- blockCounter = 0;
- for( auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock() )
- {
- UInt blockID = blockCounter++;
-
- // Loop over the instruction in the block, to allocate registers
- // for them. The parameters of a block will always be the first
- // N instructions in the block, so they will always get the
- // first N registers in that block. Similarly, the entry block
- // is always the first block, so that the parameters of the function
- // will always be the first N registers.
- //
- bcBlocks[blockID].params = bcRegs + regCounter;
- for( auto ii = bb->getFirstInst(); ii; ii = ii->getNextInst() )
- {
- switch(ii->op)
- {
- default:
- // For a parameter, or an ordinary instruction with
- // a result, allocate it here.
- if( opHasResult(ii) )
- {
- Int localID = regCounter++;
- subContext->mapInstToLocalID.Add(ii, localID);
-
- bcRegs[localID].op = ii->op;
-#if 0
- bcRegs[localID].name = tryGenerateNameForSymbol(context, ii);
-#endif
- bcRegs[localID].previousVarIndexPlusOne = (uint32_t)localID;
- bcRegs[localID].typeID = getTypeIDForGlobalSymbol(context, ii);
- }
- break;
-
- case kIROp_Var:
- // As handled in the earlier loop, we are
- // allocating *two* locations for each `var`
- // instruction. The first of these will be
- // the actual pointer value, while the second
- // will be the storage for the variable value.
- {
- Int localID = regCounter;
- regCounter += 2;
-
- subContext->mapInstToLocalID.Add(ii, localID);
- bcRegs[localID].op = ii->op;
-#if 0
- bcRegs[localID].name = tryGenerateNameForSymbol(context, ii);
-#endif
- bcRegs[localID].previousVarIndexPlusOne = (uint32_t)localID;
- bcRegs[localID].typeID = getTypeIDForGlobalSymbol(context, ii);
-
- bcRegs[localID+1].op = ii->op;
- bcRegs[localID+1].previousVarIndexPlusOne = (uint32_t)localID+1;
- bcRegs[localID+1].typeID = getTypeID(context,
- (as<IRPtrType>(ii->getDataType()))->getValueType());
- }
- break;
- }
- }
- }
- assert((UInt)regCounter == regCount);
-
- // Now that we've allocated our blocks and our registers
- // we can go through the actual process of emitting instructions. Hooray!
- blockCounter = 0;
-
- // Offset of each basic block from the start of the code
- // for the current funciton.
- List<UInt> blockOffsets;
- for( auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock() )
- {
- blockCounter++;
-
- // Get local bytecode offset for current block.
- UInt blockOffset = subContext->currentBytecode.Count();
- blockOffsets.Add( blockOffset );
-
- for( auto ii = bb->getFirstInst(); ii; ii = ii->getNextInst() )
- {
- // What we do with each instruction depends a bit on the
- // kind of instruction it is.
- switch( ii->op )
- {
- default:
- // For most instructions we just emit their bytecode
- // ops directly.
- generateBytecodeForInst(subContext, ii);
- break;
-
- case kIROp_Param:
- // Don't actually emit code for these, because
- // there isn't really anything to *execute*
- //
- // Note that we *do* allow the `var` nodes
- // to be executed, just because they need
- // to set up a register with the pointer value.
- break;
- }
- }
- }
-
-
- // We've collected bytecode for the instruction stream
- // into a sub-context, so we can now append that code.
- UInt byteCount = subContext->currentBytecode.Count();
- BytecodeGenerationPtr<uint8_t> bytes = allocateArray<uint8_t>(context, byteCount);
- memcpy(&bytes[0], subContext->currentBytecode.Buffer(), byteCount);
-
- // Now that we've allocated the storage, we can write
- // the bytecode pointers into the blocks.
- blockCounter = 0;
- for( auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock() )
- {
- UInt blockID = blockCounter++;
- bcBlocks[blockID].code = bytes + blockOffsets[blockID];
- }
-
- // Finally, after emitting all the instructions we can
- // build a table of global symbols taht need to be
- // imported into the current function as constants.
- UInt constCount = subContext->remappedGlobalSymbols.Count();
- auto bcConsts = allocateArray<BCConst>(context, constCount);
-
- bcFunc->constCount = (uint32_t)constCount;
- bcFunc->consts = bcConsts;
-
- for( UInt cc = 0; cc < constCount; ++cc )
- {
- bcConsts[cc] = subContext->remappedGlobalSymbols[cc];
- }
-
- return bcFunc;
- }
- break;
-
- case kIROp_GlobalVar:
- case kIROp_GlobalConstant:
- {
- auto bcVar = allocate<BCSymbol>(context);
-
- bcVar->op = inst->op;
- bcVar->typeID = getTypeID(context, inst->getFullType());
-
- // TODO: actually need to intialize with body instructions
-
- return bcVar;
- }
- break;
-
- default:
- // Most instructions don't need a custom representation.
- return BytecodeGenerationPtr<BCSymbol>();
- }
-}
-
-BytecodeGenerationPtr<BCModule> generateBytecodeForModule(
- BytecodeGenerationContext* context,
- IRModule* irModule)
-{
- if (!irModule)
- {
- // Not IR module? Then return a null pointer.
- return BytecodeGenerationPtr<BCModule>();
- }
-
- // A module in the bytecode is mostly just a list of the
- // global symbols in the module.
- //
- // TODO: we need to be careful and recognize the distinction
- // between the global symbols in the *AST* module, vs. those
- // symbols which are effectively global in the *IR* module.
- //
- // We probably need to store these distinctly, since we
- // need the AST global symbols for reflection, and then
- // also to reconstruct the AST on load when importing a
- // serialized module. We then need the global IR symbols
- // to use when linking, to quickly resolve things without
- // needing any semantic knowledge of nesting at the AST level.
- //
- auto bcModule = allocate<BCModule>(context);
-
- // We need to compute how many "registers" to allocate
- // for the module, where the registers represent the
- // values being computed at the global scope.
- UInt symbolCount = 0;
- for(auto ii : irModule->getGlobalInsts())
- {
- auto gv = as<IRGlobalValue>(ii);
- if (!gv)
- continue;
-
- Int globalID = Int(symbolCount++);
-
- // Ensure that local code inside functions can see these symbols
- BCConst bcConst;
- bcConst.flavor = kBCConstFlavor_GlobalSymbol;
- bcConst.id = (uint32_t)globalID;
- context->shared->mapValueToGlobal.Add(gv, bcConst);
-
- // In the global scope, global IDs are also the local IDs
- context->mapInstToLocalID.Add(gv, globalID);
- }
-
- auto bcSymbols = allocateArray<BCPtr<BCSymbol>>(context, symbolCount);
-
- bcModule->symbolCount = (uint32_t)symbolCount;
- bcModule->symbols = bcSymbols;
-
- for(auto ii : irModule->getGlobalInsts())
- {
- auto gv = as<IRGlobalValue>(ii);
- if (!gv)
- continue;
-
- UInt symbolIndex = *context->mapInstToLocalID.TryGetValue(gv);
-
- auto bcSymbol = generateBytecodeSymbolForInst(context, gv);
- if (!bcSymbol.getPtr())
- continue;
-
- auto name = tryGenerateNameForSymbol(context, gv);
- bcSymbol->name = name;
-
- bcSymbols[symbolIndex] = bcSymbol;
- }
-
- // At this point we should have identified all the literals we need:
- UInt constantCount = context->shared->constants.Count();
- auto bcConstants = allocateArray<BCConstant>(context, constantCount);
- bcModule->constantCount = (uint32_t)constantCount;
- bcModule->constants = bcConstants;
-
- for(UInt cc = 0; cc < constantCount; ++cc)
- {
- auto irConstant = (IRConstant*) context->shared->constants[cc];
- bcConstants[cc].op = irConstant->op;
- bcConstants[cc].typeID = getTypeID(context, irConstant->getFullType());
-
- switch(irConstant->op)
- {
- case kIROp_IntLit:
- {
- auto ptr = allocate<IRIntegerValue>(context);
- *ptr = irConstant->value.intVal;
- bcConstants[cc].ptr = ptr.bitCast<uint8_t>();
- }
- break;
-
- default:
- break;
- }
-
- }
-
- // At this point we should have collected all the types we need:
- UInt typeCount = context->shared->bcTypes.Count();
- auto bcTypes = allocateArray<BCPtr<BCType>>(context, typeCount);
- bcModule->typeCount = (uint32_t)typeCount;
- bcModule->types = bcTypes;
-
- for(UInt tt = 0; tt < typeCount; ++tt)
- {
- bcTypes[tt] = context->shared->bcTypes[tt];
- }
-
-
- return bcModule;
-}
-
-void generateBytecodeContainer(
- BytecodeGenerationContext* context,
- CompileRequest* compileReq)
-{
- // Header must be the very first thing in the bytecode stream
- BytecodeGenerationPtr<BCHeader> header = allocate<BCHeader>(context);
-
- memcpy(header->magic, "slang\0bc", sizeof(header->magic));
- header->version = 0;
-
- // TODO: Need to generate BC representation of all the public/exported
- // declrations in the translation units, so that they can be used to
- // resolve depenencies downstream.
-
- // TODO: Need to dump BC representation of compiled kernel codes
- // for each specified code-generation target.
-
- List<BytecodeGenerationPtr<BCModule>> bcModulesList;
- for (auto translationUnitReq : compileReq->translationUnits)
- {
- auto bcModule = generateBytecodeForModule(context, translationUnitReq->irModule);
- bcModulesList.Add(bcModule);
- }
-
- UInt bcModuleCount = bcModulesList.Count();
- header->moduleCount = (uint32_t)bcModuleCount;
-
- auto bcModules = allocateArray<BCPtr<BCModule>>(context, bcModuleCount);
- header->modules = bcModules;
- for(UInt ii = 0; ii < bcModuleCount; ++ii)
- {
- bcModules[ii] = bcModulesList[ii];
- }
-}
-
-void generateBytecodeForCompileRequest(
- CompileRequest* compileReq)
-{
- SharedBytecodeGenerationContext sharedContext;
-
- BytecodeGenerationContext context;
- context.shared = &sharedContext;
-
- generateBytecodeContainer(&context, compileReq);
-
- compileReq->generatedBytecode = sharedContext.bytecode;
-}
-
-// TODO: Need to support IR emit at the whole-module/compile-request
-// level, and not just for individual entry points.
-#if 0
-List<uint8_t> emitSlangIRForEntryPoint(
- EntryPointRequest* entryPoint)
-{
- auto compileRequest = entryPoint->compileRequest;
- auto irModule = lowerEntryPointToIR(
- entryPoint,
- compileRequest->layout.Ptr(),
- // TODO: we need to pick the target more carefully here
- CodeGenTarget::HLSL);
-
-#if 0
- String irAsm = getSlangIRAssembly(irModule);
- fprintf(stderr, "%s\n", irAsm.Buffer());
-#endif
-
- // Now we need to encode that IR into a binary format
- // for transmission/serialization/etc.
-
- SharedBytecodeGenerationContext sharedContext;
-
- BytecodeGenerationContext context;
- context.shared = &sharedContext;
-
- generateBytecodeStream(&context, irModule);
-
- return sharedContext.bytecode;
-}
-#endif
-
-} // namespace Slang
diff --git a/source/slang/bytecode.h b/source/slang/bytecode.h
deleted file mode 100644
index f1ad52c32..000000000
--- a/source/slang/bytecode.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// bytecode.h
-#ifndef SLANG_BYTECODE_H_INCLUDED
-#define SLANG_BYTECODE_H_INCLUDED
-
-// This file defines a "bytecode" format for storing shader code
-// that has been generated via the Slang IR. The bytecode has
-// two main goals, that can end up in a bit of conflict:
-//
-// 1) It is the official serialized form of the Slang IR, and
-// so it is of some importance that constructs in the IR be
-// able to round-trip through the bytecode.
-//
-// 2) It should support being directly executed/interpreted,
-// so that Slang code can be executed on CPUs when
-// performance isn't critical (or when a JIT just isn't
-// an option).
-//
-
-#include "../core/basic.h"
-
-namespace Slang
-{
-template<typename T>
-struct BytecodeGenerationPtr;
-
-// A "pointer" stored in a serialized bytecode file, which
-// is represented as a byte offset relative to itself.
-//
-template<typename T>
-struct BCPtr
-{
- typedef int32_t RawVal;
-
- RawVal rawVal;
-
- BCPtr() : rawVal(0) {}
-
- BCPtr(T* ptr)
- : rawVal(0)
- {
- *this = ptr;
- }
-
- BCPtr(BCPtr<T> const& ptr)
- : rawVal(0)
- {
- *this = ptr.getPtr();
- }
-
- void operator=(BCPtr<T> const& ptr)
- {
- *this = ptr.getPtr();
- }
-
- void operator=(T* ptr)
- {
- if (ptr)
- {
- rawVal = (RawVal)((char*)ptr - (char*)this);
- }
- else
- {
- rawVal = 0;
- }
- }
-
- operator T*() const { return getPtr(); }
- T* operator->() const { return getPtr(); }
-
- T* getPtr() const
- {
- if(!rawVal) return nullptr;
- return (T*)((char const*)this + rawVal);
- }
-};
-
-// Representation of a "type-level" value in
-// the bytecode fiel. This corresponds to
-// the AST-level notion of a `Val`
-struct BCVal
-{
- // The opcode used to define this value
- uint32_t op;
-
- // The ID of the type within its module
- uint32_t id;
-};
-
-struct BCType : BCVal
-{
- // TODO: avoid having to encode this?
- uint32_t argCount;
-
- // type-specific operands follow
-
- //
-
- BCPtr<BCVal>* getArgs() { return (BCPtr<BCVal>*) (this +1); }
-
- BCVal* getArg(UInt index) { return getArgs()[index]; }
-};
-
-struct BCPtrType : BCType
-{
- BCPtr<BCType> valueType;
-};
-
-struct BCFuncType : BCType
-{
- BCPtr<BCType> resultType;
- BCPtr<BCType> paramTypes[1];
-
- BCType* getResultType() { return resultType; }
-
- UInt getParamCount() { return argCount - 1; }
- BCType* getParamType(UInt index) { return paramTypes[index]; }
-};
-
-struct BCConstant : BCVal
-{
- uint32_t typeID;
- BCPtr<uint8_t> ptr;
-};
-
-struct BCSymbol
-{
- // The opcode that was used to define
- // this symbol; used to categorize things
- uint32_t op;
-
- // The index (in the module's type table)
- // of the type of the symbol:
- uint32_t typeID;
-
- // The name of this symbol (which might
- // be a mangled name at some point,
- // so it is really only meant to be
- // used for linkage...)
- BCPtr<char> name;
-};
-
-typedef uint8_t BCOp;
-
-struct BCReg : BCSymbol
-{
- // The index of the variable/register
- // that should be stored immediately
- // preceding this one.
- uint32_t previousVarIndexPlusOne;
-};
-
-enum BCConstFlavor
-{
- kBCConstFlavor_GlobalSymbol,
- kBCConstFlavor_Constant,
-};
-
-struct BCConst
-{
- // The flavor of bytecode constant we
- // are dealing with.
- uint32_t flavor;
- uint32_t id;
-};
-
-struct BCBlock
-{
- // The start of the bytecode for this block
- BCPtr<BCOp> code;
-
- // The list of parameters of the block
- uint32_t paramCount;
- BCPtr<BCReg> params;
-};
-
-struct BCFunc : BCSymbol
-{
- // A list of "registers" used to hold
- // intermediate values during execution
- // of this function.
- uint32_t regCount;
- BCPtr<BCReg> regs;
-
- // The basic blocks of the function
- uint32_t blockCount;
- BCPtr<BCBlock> blocks;
-
- // A list of "constants" which are values
- // from the global scope that this function
- // wants to be able to refer to. We could
- // just encode global values directly,
- // but this would make the encoding less dense.
- uint32_t constCount;
- BCPtr<BCConst> consts;
-};
-
-struct BCModule
-{
- // The symbols (functions, global variables, etc.)
- // that have been declared in the module.
- uint32_t symbolCount;
- BCPtr<BCPtr<BCSymbol>> symbols;
-
- // The types that are used by this module, stored
- // in a single array so that they can be conveniently
- // mapped to another representation in one go.
- //
- // Instructions in a bytecode instruction sequence
- // might reference these types by index.
- uint32_t typeCount;
- BCPtr<BCPtr<BCType>> types;
-
- // True compile-time constants go here:
- uint32_t constantCount;
- BCPtr<BCConstant> constants;
-};
-
-struct BCHeader
-{
- char magic[8];
- uint32_t version;
-
- // TODO: probably want a section-based file
- // format so that we can add/remove different
- // kinds of data without having to revise
- // the schema here.
-
- // TODO: should include AST declaration structure
- // here, which can be used for refleciton, and
- // also loaded to resolve dependencies when
- // compiling other modules.
-
- // TODO: Include the original entry point requests?
-
- // Zero or more IR modules, corresponding to
- // the translation units of the original compile
- // request.
- uint32_t moduleCount;
- BCPtr<BCPtr<BCModule>> modules;
-
- // TODO: should enumerate targets here, and
- // include reflection layout info + compiled
- // entry points for each target.
-};
-
-class CompileRequest;
-void generateBytecodeForCompileRequest(
- CompileRequest* compileReq);
-
-}
-
-
-#endif
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index 37e9827f8..0f333aa3d 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -5,7 +5,6 @@
#include "../core/slang-io.h"
#include "../core/slang-string-util.h"
-#include "bytecode.h"
#include "compiler.h"
#include "lexer.h"
#include "lower-to-ir.h"
@@ -1079,18 +1078,6 @@ SlangResult dissassembleDXILUsingDXC(
generateOutputForTarget(targetReq);
}
- // If we are being asked to generate code in a container
- // format, then we are now in a position to do so.
- switch (compileRequest->containerFormat)
- {
- default:
- break;
-
- case ContainerFormat::SlangModule:
- generateBytecodeForCompileRequest(compileRequest);
- break;
- }
-
// If we are in command-line mode, we might be expected to actually
// write output to one or more files here.
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 2f16f4ebc..c0715fca3 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -2617,7 +2617,20 @@ namespace Slang
}
}
- bool opHasResult(IRInst* inst);
+ bool opHasResult(IRInst* inst)
+ {
+ auto type = inst->getDataType();
+ if (!type) return false;
+
+ // As a bit of a hack right now, we need to check whether
+ // the function returns the distinguished `Void` type,
+ // since that is conceptually the same as "not returning
+ // a value."
+ if(type->op == kIROp_VoidType)
+ return false;
+
+ return true;
+ }
bool instHasUses(IRInst* inst)
{
diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj
index 6bcaac3da..c502780df 100644
--- a/source/slang/slang.vcxproj
+++ b/source/slang/slang.vcxproj
@@ -171,7 +171,6 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\slang.h" />
- <ClInclude Include="bytecode.h" />
<ClInclude Include="compiler.h" />
<ClInclude Include="core.meta.slang.h" />
<ClInclude Include="decl-defs.h" />
@@ -222,10 +221,8 @@
<ClInclude Include="type-system-shared.h" />
<ClInclude Include="val-defs.h" />
<ClInclude Include="visitor.h" />
- <ClInclude Include="vm.h" />
</ItemGroup>
<ItemGroup>
- <ClCompile Include="bytecode.cpp" />
<ClCompile Include="check.cpp" />
<ClCompile Include="compiler.cpp" />
<ClCompile Include="diagnostics.cpp" />
@@ -262,7 +259,6 @@
<ClCompile Include="token.cpp" />
<ClCompile Include="type-layout.cpp" />
<ClCompile Include="type-system-shared.cpp" />
- <ClCompile Include="vm.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="slang.natvis" />
diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters
index ce76ec77e..dc5630504 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
@@ -12,9 +12,6 @@
<ClInclude Include="..\..\slang.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="bytecode.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -165,14 +162,8 @@
<ClInclude Include="visitor.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="vm.h">
- <Filter>Header Files</Filter>
- </ClInclude>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="bytecode.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="check.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -281,9 +272,6 @@
<ClCompile Include="type-system-shared.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="vm.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="slang.natvis">
diff --git a/source/slang/vm.cpp b/source/slang/vm.cpp
deleted file mode 100644
index 0f79c763b..000000000
--- a/source/slang/vm.cpp
+++ /dev/null
@@ -1,1180 +0,0 @@
-#include "vm.h"
-
-// Implementation of the Slang bytecode VM
-//
-
-#include "bytecode.h"
-#include "ir.h"
-
-#include "../../slang.h"
-
-namespace Slang
-{
-
-struct VMValImpl
-{
- // opcode used to construct the value
- uint32_t op;
-};
-
-// Representation of a type during VM execution
-struct VMTypeImpl : VMValImpl
-{
- // number of arguments to the type
- uint32_t argCount;
-
- // Size and alignment of instances of this
- // type.
- UInt size;
- UInt alignment;
-
- // operands follow
-};
-
-struct VMVal
-{
- VMValImpl* impl;
-
- VMValImpl* getImpl() { return impl; }
-};
-
-struct VMType : VMVal
-{
- VMTypeImpl* getImpl() { return (VMTypeImpl*) impl; }
- UInt getSize() { return getImpl()->size; }
- UInt getAlignment() { return getImpl()->alignment; }
-};
-
-struct VMPtrTypeImpl : VMTypeImpl
-{
- VMType base;
-};
-
-struct VMReg
-{
- // Type that the register is meant to hold
- VMType type;
-
- // offset of the variable inside the frame
- size_t offset;
-};
-
-struct VMConst
-{
- // Type of the constant
- VMType type;
-
- // Operand address to use
- void* ptr;
-};
-
-struct VMModule;
-
-// Information about a function after it has been
-// loaded into the VM.
-struct VMFunc
-{
- // The parent module that this function belongs to
- VMModule* module;
- BCFunc* bcFunc;
-
- VMReg* regs;
- VMConst* consts;
-
- size_t frameSize;
-};
-
-struct VMFrame
-{
- // The function from which this frame was spawned
- VMFunc* func;
-
- // The parent frame on the call stack of the
- // current thread.
- VMFrame* parent;
-
- // The instruction pointer within this frame
- BCOp* ip;
-
- // Registers are stored after this point.
-};
-
-struct VM;
-
-struct VMModule
-{
- BCModule* bcModule;
- VM* vm;
- void** symbols;
- VMType* types;
-};
-
-UInt decodeUInt(BCOp** ioPtr)
-{
- BCOp* ptr = *ioPtr;
-
- UInt value = *ptr++;
- if( value < 128 )
- {
- *ioPtr = ptr;
- return value;
- }
-
- // Slower path for variable-length encoding
-
- UInt result = 0;
- for(;;)
- {
- value = value & 0x7F;
- result = (result << 7) | value;
-
- if(value < 127)
- {
- *ioPtr = ptr;
- return value;
- }
-
- value = *ptr++;
- }
-}
-
-Int decodeSInt(BCOp** ioPtr)
-{
- UInt uVal = decodeUInt(ioPtr);
- if( uVal & 1 )
- {
- return Int(~(uVal >> 1));
- }
- else
- {
- return Int(uVal >> 1);
- }
-}
-
-void* getRegPtrImpl(VMFrame* frame, UInt id)
-{
- VMFunc* vmFunc = frame->func;
- VMReg* vmReg = &vmFunc->regs[id];
- size_t offset = vmReg->offset;
-
- return (void*)((char*)frame + offset);
-}
-
-void* getOperandPtrImpl(VMFrame* frame, Int id)
-{
- if( id >= 0 )
- {
- // This ID represents a local variable/register
- // of the current call frame, and should
- // be used to index into a table of such values.
-
- return getRegPtrImpl(frame, id);
- }
- else
- {
- // This ID represents a global value that has
- // been imported into the current func, and
- // should be looked up via indirection into
- // the current module.
-
- VMFunc* vmFunc = frame->func;
- VMConst* vmConst = &vmFunc->consts[~id];
- return vmConst->ptr;
- }
-}
-
-VMType getOperandTypeImpl(VMFrame* frame, Int id)
-{
- if( id >= 0 )
- {
- return frame->func->regs[id].type;
- }
- else
- {
- return frame->func->consts[~id].type;
- }
-}
-struct VMPtrAndType
-{
- void* ptr;
- VMType type;
-};
-
-VMPtrAndType decodeOperandPtrAndType(VMFrame* frame, BCOp** ioIP)
-{
- Int id = decodeSInt(ioIP);
-
- VMPtrAndType ptrAndType;
- ptrAndType.ptr = getOperandPtrImpl(frame, id);
- ptrAndType.type = getOperandTypeImpl(frame, id);
- return ptrAndType;
-}
-
-void* decodeOperandPtrImpl(VMFrame* frame, BCOp** ioIP)
-{
- Int id = decodeSInt(ioIP);
- return getOperandPtrImpl(frame, id);
-}
-
-
-template<typename T>
-T* decodeOperandPtr(VMFrame* frame, BCOp** ioIP)
-{
- return (T*)decodeOperandPtrImpl(frame, ioIP);
-}
-
-
-template<typename T>
-T& decodeOperand(VMFrame* frame, BCOp** ioIP)
-{
- return *decodeOperandPtr<T>(frame, ioIP);
-}
-
-VMType decodeType(VMFrame* frame, BCOp** ioIP)
-{
- UInt id = decodeUInt(ioIP);
- return frame->func->module->types[id];
-}
-
-VMFunc* loadVMFunc(
- BCFunc* bcFunc,
- VMModule* vmModule);
-
-struct VMSizeAlign
-{
- UInt size;
- UInt align;
-};
-
-VMSizeAlign getVMSymbolSize(BCSymbol* symbol)
-{
- VMSizeAlign result;
- result.size = sizeof(void*);
- result.align = sizeof(void*);
- switch( symbol->op )
- {
- default:
- SLANG_UNEXPECTED("op");
- break;
-
- case kIROp_TypeKind:
- break;
-
- case kIROp_Func:
- {
- BCFunc* func = (BCFunc*) symbol;
- result.size = sizeof(VMFunc)
- + func->regCount * sizeof(VMReg)
- + func->constCount * sizeof(VMConst);
- }
- break;
- }
-
- return result;
-}
-
-VMType getType(
- VMModule* vmModule,
- uint32_t typeID)
-{
- return vmModule->types[typeID];
-}
-
-void* getGlobalPtr(
- VMModule* vmModule,
- uint32_t globalID)
-{
- return vmModule->symbols[globalID];
-}
-
-VMType getGlobalType(
- VMModule* vmModule,
- uint32_t globalID)
-{
- return getType(vmModule, vmModule->bcModule->symbols[globalID]->typeID);
-}
-
-VMFunc* loadVMFunc(
- BCFunc* bcFunc,
- VMModule* vmModule)
-{
- UInt regCount = bcFunc->regCount;
- UInt constCount = bcFunc->constCount;
- UInt vmFuncSize = sizeof(VMFunc)
- + regCount * sizeof(VMReg)
- + constCount * sizeof(VMConst);
-
- VMFunc* vmFunc = (VMFunc*) malloc(vmFuncSize);
- VMReg* vmRegs = (VMReg*) (vmFunc + 1);
- VMConst* vmConsts = (VMConst*) (vmRegs + regCount);
-
- vmFunc->module = vmModule;
- vmFunc->bcFunc = bcFunc;
- vmFunc->regs = vmRegs;
- vmFunc->consts = vmConsts;
-
- UInt offset = sizeof(VMFrame);
- for( UInt rr = 0; rr < regCount; ++rr )
- {
- BCReg* bcReg = &bcFunc->regs[rr];
- auto bcTypeID = bcReg->typeID;
-
- // We expect the type to come from the outer module, so
- // that we can allocate space for it as we go.
- auto vmType = getType(vmModule, bcTypeID);
-
- auto regSize = vmType.getSize();
- auto regAlign = vmType.getAlignment();
-
- offset = (offset + (regAlign-1)) & ~(regAlign-1);
-
- size_t regOffset = offset;
- offset += regSize;
-
- vmRegs[rr].type = vmType;
- vmRegs[rr].offset = regOffset;
- }
- vmFunc->frameSize = offset;
-
- for( UInt cc = 0; cc < constCount; ++cc )
- {
- BCConst bcConst = bcFunc->consts[cc];
- switch( bcConst.flavor )
- {
- case kBCConstFlavor_GlobalSymbol:
- {
- auto globalID = bcConst.id;
- vmFunc->consts[cc].ptr = &vmModule->symbols[globalID];
- vmFunc->consts[cc].type = getGlobalType(vmModule, globalID);
- }
- break;
-
- case kBCConstFlavor_Constant:
- {
- auto constID = bcConst.id;
- auto constInfo = &vmModule->bcModule->constants[constID];
- vmFunc->consts[cc].ptr = constInfo->ptr;
- #if 0
- fprintf(stderr, "CONSANT[%d] : [%p]\n", (int)cc, vmFunc->consts[cc].ptr);
- fprintf(stderr, "BC [%p] : %d\n", &constInfo->ptr, (int)constInfo->ptr.rawVal);
- #endif
- vmFunc->consts[cc].type = getType(vmModule, constInfo->typeID);
- }
- break;
- }
-
-
- }
-
- return vmFunc;
-}
-
-VMFrame* createFrame(VMFunc* vmFunc)
-{
- VMFrame* vmFrame = (VMFrame*) malloc(vmFunc->frameSize);
- vmFrame->func = vmFunc;
- vmFrame->ip = vmFunc->bcFunc->blocks[0].code;
- return vmFrame;
-}
-
-void dumpVMFrame(VMFrame* vmFrame)
-{
- fflush(stderr);
-
- // We want to walk the VM frame and dump the
- // state of all of its logical registers.
- // For now this is made easier by having
- // no overlapping register assignments...
- VMFunc* vmFunc = vmFrame->func;
- BCFunc* bcFunc = vmFunc->bcFunc;
- UInt regCount = bcFunc->regCount;
-
- for (UInt rr = 0; rr < regCount; ++rr)
- {
- VMType regType = getOperandTypeImpl(vmFrame, rr);
- void* regData = getRegPtrImpl(vmFrame, rr);
-
- char const* name = bcFunc->regs[rr].name;
-
- // Use the type to print the data...
-
- fprintf(stderr, "0x%p: ", regData);
-
- fprintf(stderr, "%%%u ", (unsigned int) rr);
- if (name)
- {
- fprintf(stderr, "\"%s\" ", name);
- }
- if (regType.impl)
- {
- switch (regType.impl->op)
- {
- case kIROp_TypeKind:
- // TODO: we could recursively go and print types...
- fprintf(stderr, ": Type = ???");
- break;
-
- case kIROp_HLSLRWStructuredBufferType:
- fprintf(stderr, ": RWStructuredBuffer<??\?> = ???");
- break;
-
- case kIROp_HLSLStructuredBufferType:
- fprintf(stderr, ": StructuredBuffer<??\?> = ???");
- break;
-
- case kIROp_BoolType:
- fprintf(stderr, ": Bool = %s", *(bool*)regData ? "true" : "false");
- break;
-
- case kIROp_IntType:
- fprintf(stderr, ": Int32 = %d", *(int32_t*)regData);
- break;
-
- case kIROp_UIntType:
- fprintf(stderr, ": UInt32 = %u", *(uint32_t*)regData);
- break;
-
- case kIROp_PtrType:
- {
- fprintf(stderr, ": Ptr<?> = [%p]", *(void**)regData);
- }
- break;
-
- default:
- fprintf(stderr, "<unknown>");
- break;
- }
- }
- else
- {
- fprintf(stderr, ": <null>");
- }
- fprintf(stderr, "; // ");
- fprintf(stderr, "%s", getIROpInfo((IROp) bcFunc->regs[rr].op).name);
- fprintf(stderr, "\n");
-
- // Okay, now we need to use the type
- // stored in the VM register to tell
- // us how to print things.
- }
-
- IROp op = IROp(*vmFrame->ip);
- IROpInfo opInfo = getIROpInfo(op);
- fprintf(stderr, "NEXT op: %s\n", opInfo.name);
-
- fflush(stderr);
-}
-
-struct VM
-{
-};
-
-VM* createVM()
-{
- VM* vm = new VM();
- return vm;
-}
-
-struct VMThread
-{
- // The currently executing call frame
- VMFrame* frame;
-};
-
-void resumeThread(
- VMThread* vmThread);
-
-void computeTypeSizeAlign(
- VMTypeImpl* impl)
-{
- UInt size = 0;
- UInt alignment = 0;
- switch(impl->op)
- {
- case kIROp_VoidType:
- size = 0;
- break;
-
- case kIROp_BoolType:
- size = 1;
- break;
-
- case kIROp_IntType:
- case kIROp_UIntType:
- case kIROp_FloatType:
- size = 4;
- break;
-
- case kIROp_FuncType:
- case kIROp_PtrType:
- case kIROp_HLSLRWStructuredBufferType:
- case kIROp_HLSLStructuredBufferType:
- size = sizeof(void*);
- break;
-
- default:
- SLANG_UNIMPLEMENTED_X("type sizing");
- UNREACHABLE(impl->size = 0);
- break;
- }
-
- if(!alignment)
- alignment = size;
- if(!alignment)
- alignment = 1;
-
- impl->size = size;
- impl->alignment = alignment;
-}
-
-VMType getType(
- VM* /*vm*/,
- VMTypeImpl* typeImpl)
-{
- // TODO: need to look up an existing type that matches...
-
- UInt argCount = typeImpl->argCount;
- UInt size = sizeof(VMTypeImpl) + argCount*sizeof(VMType);
-
- VMTypeImpl* impl = (VMTypeImpl*) malloc(size);
- memcpy(impl, typeImpl, size);
-
- computeTypeSizeAlign(impl);
-
- VMType type;
- type.impl = impl;
- return type;
-}
-
-VMVal getVal(
- VMModule* vmModule,
- UInt index)
-{
- return vmModule->types[index];
-}
-
-VMType loadVMType(
- VMModule* vmModule,
- BCType* bcType)
-{
- // Need to load type from BC format to VM
- IROp op = (IROp) bcType->op;
- switch(bcType->op)
- {
- case kIROp_PtrType:
- {
- // TODO: need to do some caching!
- BCPtrType* bcPtrType = (BCPtrType*) bcType;
-
- VMPtrTypeImpl vmPtrTypeImpl;
- vmPtrTypeImpl.op = op;
- vmPtrTypeImpl.argCount = 1;
- vmPtrTypeImpl.size = sizeof(void*);
- vmPtrTypeImpl.alignment = sizeof(void*);
- vmPtrTypeImpl.base = getType(vmModule, bcPtrType->valueType->id);
-
- auto vmPtrType = getType(vmModule->vm, &vmPtrTypeImpl);
- return vmPtrType;
- }
- break;
-
- default:
- {
- UInt argCount = bcType->argCount;
-
- UInt size = sizeof(VMTypeImpl) + argCount * sizeof(VMVal);
-
- VMTypeImpl* impl = (VMTypeImpl*) alloca(size);
- memset(impl, 0, size);
- impl->op = bcType->op;
- impl->argCount = (uint32_t)argCount;
-
- VMVal* args = (VMVal*) (impl + 1);
- for(UInt aa = 0; aa < argCount; ++aa)
- {
- args[aa] = getVal(vmModule, bcType->getArg(aa)->id);
- }
-
- return getType(vmModule->vm, impl);
- }
-
- UNREACHABLE(SLANG_UNEXPECTED("unimplemented"));
- UNREACHABLE_RETURN(VMType());
- break;
- }
-}
-
-void* allocateImpl(VM* /*vm*/, UInt size, UInt /*align*/)
-{
- void* ptr = malloc(size);
- memset(ptr, 0, size);
- return ptr;
-}
-
-void* allocate(VM* vm, VMType type)
-{
- return allocateImpl(vm, type.getSize(), type.getAlignment());
-}
-
-template<typename T>
-T* allocate(VM* vm)
-{
- return allocateImpl(vm, sizeof(T), alignof(T));
-}
-
-void* loadVMSymbol(
- VMModule* vmModule,
- BCSymbol* bcSymbol)
-{
- // Need to load type from BC format to VM
-
- auto vm = vmModule->vm;
-
- switch(bcSymbol->op)
- {
- case kIROp_GlobalVar:
- {
- auto type = getType(vmModule, bcSymbol->typeID);
- assert(type.impl->op == kIROp_PtrType);
-
- VMPtrTypeImpl* ptrTypeImpl = (VMPtrTypeImpl*) type.impl;
- auto valueType = ptrTypeImpl->base;
-
- void* varValue = allocate(vm, valueType);
- void** varPtr = (void**) allocate(vm, type);
-
-
- *varPtr = varValue;
-
- return varPtr;
- }
- break;
-
- case kIROp_GlobalConstant:
- {
- auto type = getType(vmModule, bcSymbol->typeID);
- void* valPtr = allocate(vm, type);
- return valPtr;
- }
- break;
-
- case kIROp_Func:
- {
- auto bcFunc = (BCFunc*) bcSymbol;
- VMFunc* vmFunc = loadVMFunc(bcFunc, vmModule);
- return vmFunc;
- }
- break;
-
- default:
- return nullptr;
- }
-}
-
-VMModule* loadVMModuleInstance(
- VM* vm,
- void const* bytecode,
- size_t /*bytecodeSize*/)
-{
- BCHeader* bcHeader = (BCHeader*) bytecode;
-
- UInt bcModuleCount = bcHeader->moduleCount;
- if (bcModuleCount == 0)
- return nullptr;
-
- BCModule* bcModule = bcHeader->modules[0];
-
- UInt symbolCount = bcModule->symbolCount;
- UInt typeCount = bcModule->typeCount;
-
- UInt vmModuleSize = sizeof(VMModule)
- + symbolCount * sizeof(void*)
- + typeCount * sizeof(VMType);
-
- VMModule* vmModule = (VMModule*)malloc(vmModuleSize);
- memset(vmModule, 0, vmModuleSize);
-
- void** vmSymbols = (void**)(vmModule + 1);
- VMType* vmTypes = (VMType*)(vmSymbols + symbolCount);
-
- vmModule->bcModule = bcModule;
- vmModule->vm = vm;
- vmModule->symbols = vmSymbols;
- vmModule->types = vmTypes;
-
- // Initialize types before symbols, since the symbols
- // will all have types...
- for(UInt tt = 0; tt < typeCount; ++tt)
- {
- BCType* bcType = bcModule->types[tt];
- vmTypes[tt] = loadVMType(vmModule, bcType);
- }
-
- // Now we need to initialize all the VM-level symbols
- // from their BC-level equivalents.
- for(UInt ss = 0; ss < symbolCount; ++ss)
- {
- BCSymbol* bcSymbol = bcModule->symbols[ss];
- vmSymbols[ss] = loadVMSymbol(vmModule, bcSymbol);
- }
-
- return vmModule;
-}
-
-void* findGlobalSymbolPtr(
- VMModule* module,
- char const* name)
-{
- // Okay, we need to search through the available
- // symbols, looking for one that gives us a name
- // match.
-
- BCModule* bcModule = module->bcModule;
- UInt symbolCount = bcModule->symbolCount;
- for(UInt ss = 0; ss < symbolCount; ++ss)
- {
- BCSymbol* bcSymbol = bcModule->symbols[ss];
-
- char const* symbolName = bcSymbol->name;
- if (!symbolName)
- continue;
-
- if(strcmp(symbolName, name) == 0)
- return getGlobalPtr(module, (uint32_t)ss);
- }
-
- return nullptr;
-}
-
-VMThread* createThread(
- VM* /*vm*/)
-{
- VMThread* thread = new VMThread();
- thread->frame = nullptr;
- return thread;
-}
-
-void beginCall(
- VMThread* vmThread,
- VMFunc* vmFunc)
-{
- VMFrame* vmFrame = createFrame(vmFunc);
-
- vmFrame->parent = vmThread->frame;
- vmThread->frame = vmFrame;
-}
-
-void setArg(
- VMThread* vmThread,
- UInt argIndex,
- void const* data,
- size_t size)
-{
- // TODO: need all kinds of validation here...
-
- void* dest = getRegPtrImpl(vmThread->frame, argIndex);
- memcpy(dest, data, size);
-}
-
-void resumeThread(
- VMThread* vmThread)
-{
- auto frame = vmThread->frame;
- auto ip = frame->ip;
-
- for(;;)
- {
-#if 0
- // debugging:
- frame->ip = ip;
- dumpVMFrame(frame);
-#endif
-
- auto op = (IROp) decodeUInt(&ip);
- switch( op )
- {
- case kIROp_Var:
- {
- // This instruction represents the `alloca` for a variable of some type.
-
- VMType type = decodeType(frame, &ip);
- UInt argCount = decodeUInt(&ip);
- void* argPtrs[16] = { 0 };
- for( UInt aa = 0; aa < argCount; ++aa )
- {
- void* argPtr = decodeOperandPtr<void>(frame, &ip);
- argPtrs[aa] = argPtr;
- }
-
- void** destPtr = decodeOperandPtr<void*>(frame, &ip);
-
- // For now this is a bit silly and simple: the
- // storage for the variable we are "allocating"
- // should be right after outer destination, so we can
- // set it pretty easily.
-
- *destPtr = destPtr + 1;
- }
- break;
-
- case kIROp_Store:
- {
- // An ordinary memory store
- VMType type = decodeType(frame, &ip);
- void* dest = decodeOperand<void*>(frame, &ip);
- void* src = decodeOperandPtr<void>(frame, &ip);
-
-#if 0
- fprintf(stderr, "STORE *[%p] = [%p] // size: %d\n",
- dest,
- src,
- (int) type.getSize());
-#endif
-
- memcpy(dest, src, type.getSize());
- }
- break;
-
- case kIROp_Load:
- {
- // An ordinary memory store
- VMType type = decodeType(frame, &ip);
- void* src = decodeOperand<void*>(frame, &ip);
- void* dest = decodeOperandPtr<void>(frame, &ip);
-
- memcpy(dest, src, type.getSize());
- }
- break;
-
- case kIROp_Call:
- {
- VMType type = decodeType(frame, &ip);
- UInt operandCount = decodeUInt(&ip);
-
- // First operand is the callee function
- VMFunc* func = decodeOperand<VMFunc*>(frame, &ip);
-
- // Okay, we need to create a frame to prepare the call
- VMFrame* newFrame = createFrame(func);
- newFrame->parent = frame;
-
- // Remaining arguments should populate the
- // first N registers of the callee
- UInt argCount = operandCount - 1;
- for( UInt aa = 0; aa < argCount; ++aa )
- {
- void* argPtr = decodeOperandPtr<void>(frame, &ip);
- void* regPtr = getRegPtrImpl(newFrame, aa);
-
- VMType regType = func->regs[aa].type;
- memcpy(regPtr, argPtr, regType.getSize());
- }
-
- // Note that we do *not* try to read off
- // the destination operand, and instead
- // leave that to be done during the
- // return sequence.
- //
-
- // Save the IP we were using in teh current function.
- //
- frame->ip = ip;
-
- // Now switch over to the callee:
- //
- frame = newFrame;
- ip = newFrame->ip;
- }
- break;
-
- case kIROp_ReturnVoid:
- {
- // Easy case: just jump to the parent frame,
- // without having to worry about operands.
- VMFrame* newFrame = frame->parent;
- vmThread->frame = newFrame;
-
- // HACK: we need to know when we are done.
- // TODO: We should probably have the bottom
- // of the stack for a thread always point
- // to a special bytecode sequence that
- // forces a `yield` op that can handle
- // the exit from the interpreter, rather
- // than always take a branch here.
- if (!newFrame)
- return;
-
- frame = newFrame;
- ip = frame->ip;
-
- }
- break;
-
- case kIROp_ReturnVal:
- {
- VMType instType = decodeType(frame, &ip);
- /*UInt argCount =*/ decodeUInt(&ip);
- void* argPtr = decodeOperandPtr<void>(frame, &ip);
-
- VMFrame* newFrame = frame->parent;
- vmThread->frame = newFrame;
-
- // Note: see the comments above about
- // this branch.
- if (!newFrame)
- return;
-
- frame = newFrame;
- ip = frame->ip;
-
- auto destPtrAndType = decodeOperandPtrAndType(frame, &ip);
- void* destPtr = destPtrAndType.ptr;
- VMType type = destPtrAndType.type;
-
- memcpy(destPtr, argPtr, type.getSize());
- }
- break;
-
- case kIROp_loop:
- case kIROp_unconditionalBranch:
- {
- // For now our encoding is very regular, so we can decode without
- // knowing too much about an instruction...
-
- VMType type = decodeType(frame, &ip);
- UInt argCount = decodeUInt(&ip);
- Int destinationBlockIndex = decodeSInt(&ip);
-
- auto func = frame->func;
- auto& destinationBlock = func->bcFunc->blocks[destinationBlockIndex];
-
- // We may be passing arguments through to the destination
- // block, so any remaining operands of the branch instruction
- // need to be used to fill in the parameter registers of
- // the destination block.
-
- UInt paramCount = destinationBlock.paramCount;
-
- // There might be additional operands, because some branches
- // also include information on merge points and break/continue labels.
- UInt remainingArgCount = argCount - 1;
- assert(remainingArgCount >= paramCount);
-
- UInt extraArgCount = remainingArgCount - paramCount;
-
- for (UInt ee = 0; ee < extraArgCount; ++ee)
- {
- decodeOperandPtr<void>(frame, &ip);
- }
-
- auto baseRegIndex = destinationBlock.params - func->bcFunc->regs;
- for( UInt pp = 0; pp < paramCount; ++pp )
- {
- auto regIndex = baseRegIndex + pp;
-
- void* argPtr = decodeOperandPtr<void>(frame, &ip);
- void* regPtr = getRegPtrImpl(frame, regIndex);
-
- VMType regType = func->regs[regIndex].type;
- memcpy(regPtr, argPtr, regType.getSize());
- }
-
- // Now simply jump to the destination block.
- //
- ip = destinationBlock.code;
- }
- break;
-
- case kIROp_ifElse:
- case kIROp_conditionalBranch:
- {
- // For now our encoding is very regular, so we can decode without
- // knowing too much about an instruction...
-
- VMType type = decodeType(frame, &ip);
- UInt argCount = decodeUInt(&ip);
- bool* condition = decodeOperandPtr<bool>(frame, &ip);
- Int trueBlockID = decodeSInt(&ip);
- Int falseBlockID = decodeSInt(&ip);
- for( UInt aa = 4; aa < argCount; ++aa )
- {
- decodeOperandPtr<void>(frame, &ip);
- }
-
- Int destinationBlock = *condition ? trueBlockID : falseBlockID;
-
- // TODO: we need to deal with the case of
- // passing arguments to the block, which
- // means copying between the registers...
- //
- ip = frame->func->bcFunc->blocks[destinationBlock].code;
- }
- break;
-
- case kIROp_Greater:
- {
- // For now our encoding is very regular, so we can decode without
- // knowing too much about an instruction...
-
- VMType resultType = decodeType(frame, &ip);
- /*UInt argCount = */decodeUInt(&ip);
- //void* argPtrs[16] = { 0 };
- auto leftOpnd = decodeOperandPtrAndType(frame, &ip);
- auto type = leftOpnd.type;
- auto leftPtr = leftOpnd.ptr;
- void* rightPtr = decodeOperandPtr<void>(frame, &ip);
-
- bool* destPtr = decodeOperandPtr<bool>(frame, &ip);
-
- switch (type.impl->op)
- {
- case kIROp_IntType:
- *destPtr = *(int32_t*)leftPtr > *(int32_t*)rightPtr;
- break;
-
- default:
- SLANG_UNEXPECTED("comparison op case");
- break;
- }
- }
- break;
-
- case kIROp_Mul:
- {
- VMType type = decodeType(frame, &ip);
- /*UInt argCount = */decodeUInt(&ip);
- void* leftPtr = decodeOperandPtr<void>(frame, &ip);
- void* rightPtr = decodeOperandPtr<void>(frame, &ip);
-
- void* destPtr = decodeOperandPtr<void>(frame, &ip);
-
- switch (type.impl->op)
- {
- case kIROp_IntType:
- *(int32_t*)destPtr = *(int32_t*)leftPtr * *(int32_t*)rightPtr;
- break;
-
- default:
- SLANG_UNEXPECTED("comparison op case");
- break;
- }
- }
- break;
-
- case kIROp_Sub:
- {
- VMType type = decodeType(frame, &ip);
- /*UInt argCount = */decodeUInt(&ip);
- void* leftPtr = decodeOperandPtr<void>(frame, &ip);
- void* rightPtr = decodeOperandPtr<void>(frame, &ip);
-
- void* destPtr = decodeOperandPtr<void>(frame, &ip);
-
- switch (type.impl->op)
- {
- case kIROp_IntType:
- *(int32_t*)destPtr = *(int32_t*)leftPtr - *(int32_t*)rightPtr;
- break;
-
- default:
- SLANG_UNEXPECTED("comparison op case");
- break;
- }
- }
- break;
-
- default:
- {
- // For now our encoding is very regular, so we can decode without
- // knowing too much about an instruction...
-
- VMType type = decodeType(frame, &ip);
- UInt argCount = decodeUInt(&ip);
- void* argPtrs[16] = { 0 };
- for( UInt aa = 0; aa < argCount; ++aa )
- {
- void* argPtr = decodeOperandPtr<void>(frame, &ip);
- argPtrs[aa] = argPtr;
- }
-
- SLANG_UNEXPECTED("unknown bytecode op");
- return;
- }
- break;
- }
- }
-
-}
-
-
-
-
-SLANG_API void SlangVMThread_resume(
- SlangVMThread* thread)
-{
- Slang::resumeThread(
- (Slang::VMThread*) thread);
-}
-
-} // namespace Slang
-
-SLANG_API SlangVM* SlangVM_create()
-{
- return (SlangVM*) Slang::createVM();
-}
-
-SLANG_API SlangVMModule* SlangVMModule_load(
- SlangVM* vm,
- void const* bytecode,
- size_t bytecodeSize)
-{
- return (SlangVMModule*) Slang::loadVMModuleInstance(
- (Slang::VM*) vm,
- bytecode,
- bytecodeSize);
-}
-
-SLANG_API void* SlangVMModule_findGlobalSymbolPtr(
- SlangVMModule* module,
- char const* name)
-{
- return (SlangVMFunc*) Slang::findGlobalSymbolPtr(
- (Slang::VMModule*) module,
- name);
-}
-
-SLANG_API SlangVMThread* SlangVMThread_create(
- SlangVM* vm)
-{
- return (SlangVMThread*)Slang::createThread(
- (Slang::VM*) vm);
-}
-
-SLANG_API void SlangVMThread_beginCall(
- SlangVMThread* thread,
- SlangVMFunc* func)
-{
- Slang::beginCall(
- (Slang::VMThread*) thread,
- (Slang::VMFunc*) func);
-}
-
-SLANG_API void SlangVMThread_setArg(
- SlangVMThread* thread,
- SlangUInt argIndex,
- void const* data,
- size_t size)
-{
- Slang::setArg(
- (Slang::VMThread*) thread,
- argIndex,
- data,
- size);
-}
-
-SLANG_API void SlangVMThread_resume(
- SlangVMThread* thread)
-{
- Slang::resumeThread(
- (Slang::VMThread*) thread);
-}
diff --git a/source/slang/vm.h b/source/slang/vm.h
deleted file mode 100644
index e67fec43a..000000000
--- a/source/slang/vm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// vm.h
-#ifndef SLANG_VM_H_INCLUDED
-#define SLANG_VM_H_INCLUDED
-
-// This file defines a virtual machine for executing
-// code that has been converted to Slang bytecode.
-//
-
-#include "../core/basic.h"
-
-namespace Slang
-{
-
-
-
-}
-
-
-#endif
diff --git a/tools/slang-eval-test/main.cpp b/tools/slang-eval-test/main.cpp
deleted file mode 100644
index ff2ebed34..000000000
--- a/tools/slang-eval-test/main.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-// main.cpp
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "../../source/core/secure-crt.h"
-#include <slang.h>
-
-static SlangResult innerMain(int argc, char*const* argv)
-{
- // TODO: parse arguments
-
- assert(argc >= 2);
- char const* inputPath = argv[1];
-
- // Slurp in the input file, so that we can compile and run it
- FILE* inputFile;
- fopen_s(&inputFile, inputPath, "rb");
- assert(inputFile);
-
- fseek(inputFile, 0, SEEK_END);
- size_t inputSize = ftell(inputFile);
- fseek(inputFile, 0, SEEK_SET);
-
- char* inputText = (char*)malloc(inputSize + 1);
- fread(inputText, inputSize, 1, inputFile);
- inputText[inputSize] = 0;
- fclose(inputFile);
-
- // TODO: scan through the text to find comments,
- // that instruct us how to generate input and
- // consume output when running the test.
-
- //
-
- SlangSession* session = spCreateSession(nullptr);
- SlangCompileRequest* request = spCreateCompileRequest(session);
-
- spSetOutputContainerFormat(
- request,
- SLANG_CONTAINER_FORMAT_SLANG_MODULE);
-
- int translationUnitIndex = spAddTranslationUnit(
- request,
- SLANG_SOURCE_LANGUAGE_SLANG,
- nullptr);
-
- spAddTranslationUnitSourceString(
- request,
- translationUnitIndex,
- inputPath,
- inputText);
-
- int entryPointIndex = spAddEntryPoint(
- request,
- translationUnitIndex,
- "main",
- spFindProfile(session, "cs_5_0"));
-
- if (SLANG_FAILED(spCompile(request)))
- {
- char const* output = spGetDiagnosticOutput(request);
- fputs(output, stderr);
- return SLANG_FAIL;
- }
-
- // Things compiled, so now we need to run them...
-
- // Extract the bytecode
- size_t bytecodeSize = 0;
- void const* bytecode = spGetCompileRequestCode(request, &bytecodeSize);
-
- // Now we need to create an execution context to go and run the bytecode we got
-
- SlangVM* vm = SlangVM_create();
-
- SlangVMModule* vmModule = SlangVMModule_load(
- vm,
- bytecode,
- bytecodeSize);
-
- SlangVMFunc* vmFunc = (SlangVMFunc*)SlangVMModule_findGlobalSymbolPtr(
- vmModule,
- "main");
-
- int32_t*& inputArg = *(int32_t**)SlangVMModule_findGlobalSymbolPtr(
- vmModule,
- "input");
-
- int32_t*& outputArg = *(int32_t**)SlangVMModule_findGlobalSymbolPtr(
- vmModule,
- "output");
-
- SlangVMThread* vmThread = SlangVMThread_create(
- vm);
-
- int32_t inputData[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
- int32_t outputData[8] = { 0 };
-
- inputArg = inputData;
- outputArg = outputData;
-
- // TODO: set arguments based on specification from the user...
- for (uint32_t threadID = 0; threadID < 8; ++threadID)
- {
-#if 0
- fprintf(stderr, "\n\nthreadID = %u\n\n", threadID);
- fflush(stderr);
-#endif
-
- SlangVMThread_beginCall(vmThread, vmFunc);
-
- SlangVMThread_setArg(
- vmThread,
- 0,
- &threadID,
- sizeof(threadID));
-
- SlangVMThread_resume(vmThread);
- }
-
- for (uint32_t ii = 0; ii < 8; ++ii)
- {
- fprintf(stdout, "outputData[%u] = %d\n", ii, outputData[ii]);
- }
-
- spDestroyCompileRequest(request);
- spDestroySession(session);
-
- return SLANG_OK;
-}
-
-int main(
- int argc,
- char** argv)
-{
- SlangResult res = innerMain(argc, argv);
- return SLANG_FAILED(res) ? 1 : 0;
-}
diff --git a/tools/slang-eval-test/slang-eval-test.vcxproj b/tools/slang-eval-test/slang-eval-test.vcxproj
deleted file mode 100644
index c7b214d4a..000000000
--- a/tools/slang-eval-test/slang-eval-test.vcxproj
+++ /dev/null
@@ -1,178 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{205FCAB9-A13F-4980-86FA-F6221A7095EE}</ProjectGuid>
- <IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>slang-eval-test</RootNamespace>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- <OutDir>..\..\bin\windows-x86\debug\</OutDir>
- <IntDir>..\..\intermediate\windows-x86\debug\slang-eval-test\</IntDir>
- <TargetName>slang-eval-test</TargetName>
- <TargetExt>.exe</TargetExt>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- <OutDir>..\..\bin\windows-x64\debug\</OutDir>
- <IntDir>..\..\intermediate\windows-x64\debug\slang-eval-test\</IntDir>
- <TargetName>slang-eval-test</TargetName>
- <TargetExt>.exe</TargetExt>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- <OutDir>..\..\bin\windows-x86\release\</OutDir>
- <IntDir>..\..\intermediate\windows-x86\release\slang-eval-test\</IntDir>
- <TargetName>slang-eval-test</TargetName>
- <TargetExt>.exe</TargetExt>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- <OutDir>..\..\bin\windows-x64\release\</OutDir>
- <IntDir>..\..\intermediate\windows-x64\release\slang-eval-test\</IntDir>
- <TargetName>slang-eval-test</TargetName>
- <TargetExt>.exe</TargetExt>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <Optimization>Disabled</Optimization>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <Optimization>Disabled</Optimization>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <Optimization>Full</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <MinimalRebuild>false</MinimalRebuild>
- <StringPooling>true</StringPooling>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <Optimization>Full</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <MinimalRebuild>false</MinimalRebuild>
- <StringPooling>true</StringPooling>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="main.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\source\core\core.vcxproj">
- <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
- </ProjectReference>
- <ProjectReference Include="..\..\source\slang\slang.vcxproj">
- <Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/tools/slang-eval-test/slang-eval-test.vcxproj.filters b/tools/slang-eval-test/slang-eval-test.vcxproj.filters
deleted file mode 100644
index e9ae1c092..000000000
--- a/tools/slang-eval-test/slang-eval-test.vcxproj.filters
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="main.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp
index f710d63f2..943e82cef 100644
--- a/tools/slang-test/main.cpp
+++ b/tools/slang-test/main.cpp
@@ -853,53 +853,6 @@ String getExpectedOutput(String const& outputStem)
return expectedOutput;
}
-TestResult runEvalTest(TestContext* context, TestInput& input)
-{
- // We are going to load and evaluate the code
-
- auto filePath = input.filePath;
- auto outputStem = input.outputStem;
-
- OSProcessSpawner spawner;
-
- spawner.pushExecutablePath(String(g_options.binDir) + "slang-eval-test" + osGetExecutableSuffix());
- spawner.pushArgument(filePath);
-
- for( auto arg : input.testOptions->args )
- {
- spawner.pushArgument(arg);
- }
-
- if (spawnAndWait(context, outputStem, spawner) != kOSError_None)
- {
- return TestResult::Fail;
- }
-
- String actualOutput = getOutput(spawner);
- String expectedOutput = getExpectedOutput(outputStem);
-
- TestResult result = TestResult::Pass;
-
- // Otherwise we compare to the expected output
- if (actualOutput != expectedOutput)
- {
- result = TestResult::Fail;
- }
-
- // If the test failed, then we write the actual output to a file
- // so that we can easily diff it from the command line and
- // diagnose the problem.
- if (result == TestResult::Fail)
- {
- String actualOutputPath = outputStem + ".actual";
- Slang::File::WriteAllText(actualOutputPath, actualOutput);
-
- context->dumpOutputDifference(expectedOutput, actualOutput);
- }
-
- return result;
-}
-
static SlangCompileTarget _getCompileTarget(const UnownedStringSlice& name)
{
#define CASE(NAME, TARGET) if(name == NAME) return SLANG_##TARGET;
@@ -1706,7 +1659,6 @@ TestResult runTest(
#endif
{ "COMPARE_GLSL", &runGLSLComparisonTest },
{ "CROSS_COMPILE", &runCrossCompilerTest },
- { "EVAL", &runEvalTest },
{ nullptr, nullptr },
};