diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang-rt/slang-rt.cpp | 11 | ||||
| -rw-r--r-- | source/slang-rt/slang-rt.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 44 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-com-interface.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-dll-import.cpp | 28 | ||||
| -rw-r--r-- | source/slang/slang-ir-dll-import.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-generics-lowering-context.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-layout.cpp | 13 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-generics.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-marshal-native-call.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir.h | 13 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 50 | ||||
| -rw-r--r-- | source/slangc/main.cpp | 1 |
15 files changed, 162 insertions, 25 deletions
diff --git a/source/slang-rt/slang-rt.cpp b/source/slang-rt/slang-rt.cpp index 94699dfa0..49d4f2c9a 100644 --- a/source/slang-rt/slang-rt.cpp +++ b/source/slang-rt/slang-rt.cpp @@ -25,7 +25,7 @@ extern "C" ComPtr<ISlangSharedLibrary> lib; if (!slangRT_loadedLibraries.TryGetValue(modulePath, lib)) { - if (DefaultSharedLibraryLoader::getSingleton()->loadPlatformSharedLibrary( + if (DefaultSharedLibraryLoader::getSingleton()->loadSharedLibrary( modulePath.getBuffer(), lib.writeRef()) != SLANG_OK) { _slang_rt_abort("Failed to load DLL \"" + modulePath + "\""); @@ -36,7 +36,7 @@ extern "C" } SLANG_RT_API void* SLANG_MCALL - _slang_rt_load_dll_func(void* moduleHandle, Slang::String funcName) + _slang_rt_load_dll_func(void* moduleHandle, Slang::String funcName, uint32_t argSize) { if (moduleHandle == nullptr) { @@ -46,6 +46,13 @@ extern "C" auto funcPtr = lib->findFuncByName(funcName.getBuffer()); if (!funcPtr) { + // If failed, try stdcall mangled name. + StringBuilder sb; + sb << "_" << funcName << "@" << argSize; + funcPtr = lib->findFuncByName(sb.ToString().getBuffer()); + } + if (!funcPtr) + { _slang_rt_abort("Cannot find function \"" + funcName + "\" in loaded library."); } return (void*)funcPtr; diff --git a/source/slang-rt/slang-rt.h b/source/slang-rt/slang-rt.h index 3941b3acc..69d8a875b 100644 --- a/source/slang-rt/slang-rt.h +++ b/source/slang-rt/slang-rt.h @@ -26,7 +26,7 @@ extern "C" SLANG_RT_API void SLANG_MCALL _slang_rt_abort(Slang::String errorMessage); SLANG_RT_API void* SLANG_MCALL _slang_rt_load_dll(Slang::String modulePath); SLANG_RT_API void* SLANG_MCALL - _slang_rt_load_dll_func(void* moduleHandle, Slang::String modulePath); + _slang_rt_load_dll_func(void* moduleHandle, Slang::String modulePath, uint32_t argSize); } #endif diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 226e29764..e98c8c6f3 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -3378,16 +3378,25 @@ void CLikeSourceEmitter::ensureInstOperandsRec(ComputeEmitActionsContext* ctx, I auto requiredLevel = EmitAction::Definition; switch (inst->getOp()) { - case kIROp_InterfaceType: - requiredLevel = EmitAction::ForwardDeclaration; - break; - case kIROp_COMWitnessDecoration: + case kIROp_NativePtrType: requiredLevel = EmitAction::ForwardDeclaration; break; default: break; } + if (auto comWitnessDecoration = as<IRCOMWitnessDecoration>(inst)) + { + // A COMWitnessDecoration marks the interface inheritance of a class. + // We need to make sure the implemented interface is emited before the class. + // The witness table itself doesn't matter. + if (auto witnessTable = as<IRWitnessTable>(comWitnessDecoration->getWitnessTable())) + { + ensureInstOperand(ctx, witnessTable->getConformanceType(), requiredLevel); + } + requiredLevel = EmitAction::ForwardDeclaration; + } + for(UInt ii = 0; ii < operandCount; ++ii) { // TODO: there are some special cases we can add here, @@ -3415,13 +3424,26 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst { case kIROp_Generic: return; - + case kIROp_ThisType: + return; default: break; } if (as<IRBasicType>(inst)) return; + // Certain inst ops will always emit as definition. + switch (inst->getOp()) + { + case kIROp_NativePtrType: + // Pointer type will have their value type emited as forward declaration, + // but the pointer type itself should be considered emitted as definition. + requiredLevel = EmitAction::Level::Definition; + break; + default: + break; + } + // Have we already processed this instruction? EmitAction::Level existingLevel; if(ctx->mapInstToLevel.TryGetValue(inst, existingLevel)) @@ -3457,7 +3479,9 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst switch (inst->getOp()) { case kIROp_InterfaceRequirementEntry: + { return; + } default: break; @@ -3496,6 +3520,16 @@ void CLikeSourceEmitter::emitForwardDeclaration(IRInst* inst) m_writer->emit(getName(inst)); m_writer->emit(";\n"); break; + case kIROp_InterfaceType: + { + if (inst->findDecoration<IRComInterfaceDecoration>()) + { + m_writer->emit("struct "); + m_writer->emit(getName(inst)); + m_writer->emit(";\n"); + } + break; + } default: SLANG_UNREACHABLE("emit forward declaration"); } diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 3cfe4d8d4..345b6548a 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1775,7 +1775,7 @@ void CPPSourceEmitter::emitComInterface(IRInterfaceType* interfaceType) for (UInt i = 0; i < interfaceType->getOperandCount(); i++) { auto entry = as<IRInterfaceRequirementEntry>(interfaceType->getOperand(i)); - if (auto witnessTableType = as<IRWitnessTableType>(entry->getRequirementVal())) + if (auto witnessTableType = as<IRWitnessTableTypeBase>(entry->getRequirementVal())) { if (isFirst) { @@ -2931,6 +2931,7 @@ void CPPSourceEmitter::_emitForwardDeclarations(const List<EmitAction>& actions) { case kIROp_Func: case kIROp_StructType: + case kIROp_InterfaceType: emitForwardDeclaration(action.inst); break; default: diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 4cbfa97ab..6e78c82dc 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -218,7 +218,7 @@ Result linkAndOptimizeIR( case CodeGenTarget::HostCPPSource: { lowerComInterfaces(irModule, artifactDesc.style, sink); - generateDllImportFuncs(irModule, sink); + generateDllImportFuncs(codeGenContext->getTargetReq(), irModule, sink); generateDllExportFuncs(irModule, sink); break; } diff --git a/source/slang/slang-ir-com-interface.cpp b/source/slang/slang-ir-com-interface.cpp index d9d54d9d2..3e52054cd 100644 --- a/source/slang/slang-ir-com-interface.cpp +++ b/source/slang/slang-ir-com-interface.cpp @@ -16,6 +16,8 @@ static bool _canReplace(IRUse* use) case kIROp_WitnessTableType: case kIROp_RTTIPointerType: case kIROp_RTTIHandleType: + case kIROp_ComPtrType: + case kIROp_NativePtrType: { // Don't replace return false; @@ -25,7 +27,6 @@ static bool _canReplace(IRUse* use) // Appears replacable. break; } - case kIROp_ComPtrType: case kIROp_PtrType: { // We can have ** and ComPtr<T>*. @@ -98,7 +99,7 @@ void lowerComInterfaces(IRModule* module, ArtifactStyle artifactStyle, Diagnosti // so has to be a raw pointer IRType* result = (artifactStyle == ArtifactStyle::Host) ? static_cast<IRType*>(builder.getComPtrType(comIntf)) : - static_cast<IRType*>(builder.getPtrType(comIntf)); + static_cast<IRType*>(builder.getNativePtrType(comIntf)); // Go through replacing all of the replacable uses for (auto use : uses) diff --git a/source/slang/slang-ir-dll-import.cpp b/source/slang/slang-ir-dll-import.cpp index 01e1241ff..bfd384f70 100644 --- a/source/slang/slang-ir-dll-import.cpp +++ b/source/slang/slang-ir-dll-import.cpp @@ -4,6 +4,7 @@ #include "slang-ir.h" #include "slang-ir-insts.h" #include "slang-ir-marshal-native-call.h" +#include "slang-ir-layout.h" namespace Slang { @@ -12,6 +13,7 @@ struct DllImportContext { IRModule* module; DiagnosticSink* diagnosticSink; + TargetRequest* targetReq; SharedIRBuilder sharedBuilder; @@ -56,12 +58,13 @@ struct DllImportContext builder.setInsertInto(module->getModuleInst()); IRType* stringType = builder.getStringType(); - IRType* paramTypes[] = {builder.getPtrType(builder.getVoidType()), stringType}; + IRType* uintType = builder.getUIntType(); + IRType* paramTypes[] = {builder.getPtrType(builder.getVoidType()), stringType, uintType }; loadFuncPtrFunc = createBuiltinIntrinsicFunc( - 2, + 3, paramTypes, builder.getPtrType(builder.getVoidType()), - UnownedStringSlice("_slang_rt_load_dll_func($0, $1)")); + UnownedStringSlice("_slang_rt_load_dll_func($0, $1, $2)")); } return loadFuncPtrFunc; } @@ -84,6 +87,17 @@ struct DllImportContext return stringGetBufferFunc; } + uint32_t getStdCallArgumentSize(IRFunc* func) + { + uint32_t result = 0; + for (auto param : func->getParams()) + { + IRSizeAndAlignment sizeAndAlignment; + getNaturalSizeAndAlignment(targetReq, param->getDataType(), &sizeAndAlignment); + result += (uint32_t)align(sizeAndAlignment.size, 4); + } + return result; + } void processFunc(IRFunc* func, IRDllImportDecoration* dllImportDecoration) { @@ -136,10 +150,11 @@ struct DllImportContext getLoadDllFunc(), builder.getStringValue(dllImportDecoration->getLibraryName())); } + auto argumentSize = builder.getIntValue(builder.getUIntType(), getStdCallArgumentSize(func)); IRInst* loadDllFuncArgs[] = { - modulePtr, builder.getStringValue(dllImportDecoration->getFunctionName())}; + modulePtr, builder.getStringValue(dllImportDecoration->getFunctionName()), argumentSize}; auto loadedNativeFuncPtr = builder.emitCallInst( - builder.getPtrType(builder.getVoidType()), getLoadFuncPtrFunc(), 2, loadDllFuncArgs); + builder.getPtrType(builder.getVoidType()), getLoadFuncPtrFunc(), 3, loadDllFuncArgs); builder.emitStore( funcPtr, builder.emitBitCast(nativeType, loadedNativeFuncPtr)); builder.emitBranch(afterBlock); @@ -175,10 +190,11 @@ struct DllImportContext } }; -void generateDllImportFuncs(IRModule* module, DiagnosticSink* sink) +void generateDllImportFuncs(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink) { DllImportContext context; context.module = module; + context.targetReq = targetReq; context.diagnosticSink = sink; context.sharedBuilder.init(module); return context.processModule(); diff --git a/source/slang/slang-ir-dll-import.h b/source/slang/slang-ir-dll-import.h index d2dc1a9a3..8ea97527b 100644 --- a/source/slang/slang-ir-dll-import.h +++ b/source/slang/slang-ir-dll-import.h @@ -5,6 +5,7 @@ namespace Slang { struct IRModule; class DiagnosticSink; + class TargetRequest; /// Generate implementations for functions marked as [DllImport]. - void generateDllImportFuncs(IRModule* module, DiagnosticSink* sink); + void generateDllImportFuncs(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink); } diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp index fbe298d3f..48178340d 100644 --- a/source/slang/slang-ir-generics-lowering-context.cpp +++ b/source/slang/slang-ir-generics-lowering-context.cpp @@ -45,9 +45,7 @@ namespace Slang return true; } - // TODO(JS): Perhaps it should do IRPtrTypeBase, or some more expansive set of 'PtrType's - // but for now test for PtrType - if (auto ptrType = as<IRPtrType>(type)) + if (auto ptrType = as<IRNativePtrType>(type)) { auto valueType = ptrType->getValueType(); return valueType->findDecoration<IRComInterfaceDecoration>() != nullptr; diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp index cbf0a6e61..0e4ccc1fe 100644 --- a/source/slang/slang-ir-layout.cpp +++ b/source/slang/slang-ir-layout.cpp @@ -256,6 +256,19 @@ static Result _calcNaturalSizeAndAlignment( outSizeAndAlignment); } break; + case kIROp_OutType: + case kIROp_InOutType: + case kIROp_RefType: + case kIROp_RawPointerType: + case kIROp_PtrType: + case kIROp_NativePtrType: + case kIROp_ComPtrType: + case kIROp_NativeStringType: + { + *outSizeAndAlignment = IRSizeAndAlignment(sizeof(void*), sizeof(void*)); + return SLANG_OK; + } + break; default: break; } diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index c95f6976c..6b8150605 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -55,6 +55,9 @@ namespace Slang switch (inst->getOp()) { case kIROp_WitnessTableIDType: + if (isComInterfaceType((IRType*)inst->getOperand(0))) + continue; + // fall through case kIROp_RTTIHandleType: { IRBuilder builder(sharedContext->sharedBuilderStorage); diff --git a/source/slang/slang-ir-marshal-native-call.cpp b/source/slang/slang-ir-marshal-native-call.cpp index 8a97bfd3e..e4c202798 100644 --- a/source/slang/slang-ir-marshal-native-call.cpp +++ b/source/slang/slang-ir-marshal-native-call.cpp @@ -16,6 +16,10 @@ namespace Slang return builder.getNativePtrType(type); case kIROp_ComPtrType: return builder.getNativePtrType((IRType*)as<IRComPtrType>(type)->getOperand(0)); + case kIROp_InOutType: + case kIROp_RefType: + case kIROp_OutType: + return builder.getPtrType(getNativeType(builder, (IRType*)type->getOperand(0))); default: return type; } @@ -72,6 +76,7 @@ namespace Slang { case kIROp_InOutType: case kIROp_RefType: + case kIROp_OutType: return marshalRefManagedValueToNativeValue( builder, originalArg, args); case kIROp_StringType: diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h index 47c6621f3..aea425a9b 100644 --- a/source/slang/slang-ir.h +++ b/source/slang/slang-ir.h @@ -1306,8 +1306,17 @@ SIMPLE_IR_PARENT_TYPE(OutTypeBase, PtrTypeBase) SIMPLE_IR_TYPE(OutType, OutTypeBase) SIMPLE_IR_TYPE(InOutType, OutTypeBase) -SIMPLE_IR_TYPE(ComPtrType, Type) -SIMPLE_IR_TYPE(NativePtrType, Type) +struct IRComPtrType : public IRType +{ + IR_LEAF_ISA(ComPtrType); + IRType* getValueType() { return (IRType*)getOperand(0); } +}; + +struct IRNativePtrType : public IRType +{ + IR_LEAF_ISA(NativePtrType); + IRType* getValueType() { return (IRType*)getOperand(0); } +}; struct IRPseudoPtrType : public IRPtrTypeBase { diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 1f3da064a..1285afca8 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -1185,6 +1185,31 @@ static void addLinkageDecoration( addLinkageDecoration(context, inst, decl, mangledName.getUnownedSlice()); } +bool shouldDeclBeTreatedAsInterfaceRequirement(Decl* requirementDecl) +{ + if (auto funcDecl = as<CallableDecl>(requirementDecl)) + { + } + else if (auto propertyDecl = as<PropertyDecl>(requirementDecl)) + { + } + else if (auto assocTypeDecl = as<AssocTypeDecl>(requirementDecl)) + { + } + else if (auto typeConstraint = as<TypeConstraintDecl>(requirementDecl)) + { + } + else if (auto genericDecl = as<GenericDecl>(requirementDecl)) + { + return shouldDeclBeTreatedAsInterfaceRequirement(genericDecl->inner); + } + else + { + return false; + } + return true; +} + IRStructKey* getInterfaceRequirementKey( IRGenContext* context, Decl* requirementDecl) @@ -1195,6 +1220,12 @@ IRStructKey* getInterfaceRequirementKey( // decl as the requirement key. if (auto genericDecl = as<GenericDecl>(requirementDecl)) return getInterfaceRequirementKey(context, genericDecl->inner); + + // Only specific types of decls are treated as requirements, e.g. methods and asssociated types. + // Other types of decls are allowed but not regarded as a requirement. + if (!shouldDeclBeTreatedAsInterfaceRequirement(requirementDecl)) + return nullptr; + IRStructKey* requirementKey = nullptr; if(context->shared->interfaceRequirementKeys.TryGetValue(requirementDecl, requirementKey)) { @@ -1356,6 +1387,9 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower // auto irReqKey = getInterfaceRequirementKey(context, reqDeclRef.getDecl()); + if (!irReqKey) + continue; + // We expect that each of the witness tables in `caseWitnessTables` // will have an entry to match these keys. However, we may not // have a concrete `IRWitnessTable` for each of the case types, either @@ -5866,6 +5900,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> auto satisfyingWitness = entry.Value; auto irRequirementKey = getInterfaceRequirementKey(requiredMemberDecl); + if (!irRequirementKey) continue; + IRInst* irSatisfyingVal = nullptr; switch(satisfyingWitness.getFlavor()) @@ -6613,6 +6649,9 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> UInt operandCount = 0; for (auto requirementDecl : decl->members) { + if (!shouldDeclBeTreatedAsInterfaceRequirement(requirementDecl)) + continue; + operandCount++; // As a special case, any type constraints placed // on an associated type will *also* need to be turned @@ -6647,8 +6686,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> for (auto requirementDecl : decl->members) { + auto requirementKey = getInterfaceRequirementKey(requirementDecl); + if (!requirementKey) continue; auto entry = subBuilder->createInterfaceRequirementEntry( - getInterfaceRequirementKey(requirementDecl), + requirementKey, nullptr); if (auto inheritance = as<InheritanceDecl>(requirementDecl)) { @@ -8551,6 +8592,13 @@ static void ensureAllDeclsRec( ensureAllDeclsRec(context, memberDecl); } } + else if (auto namespaceDecl = as<NamespaceDecl>(decl)) + { + for (auto memberDecl : namespaceDecl->members) + { + ensureAllDeclsRec(context, memberDecl); + } + } else if (auto genericDecl = as<GenericDecl>(decl)) { ensureAllDeclsRec(context, genericDecl->inner); diff --git a/source/slangc/main.cpp b/source/slangc/main.cpp index 887eca77a..2870a5a3c 100644 --- a/source/slangc/main.cpp +++ b/source/slangc/main.cpp @@ -89,6 +89,7 @@ SLANG_TEST_TOOL_API SlangResult innerMain(StdWriters* stdWriters, slang::IGlobal } SlangCompileRequest* compileRequest = spCreateCompileRequest(session); + compileRequest->addSearchPath(Path::getParentDirectory(Path::getExecutablePath()).getBuffer()); SlangResult res = _compile(compileRequest, argc, argv); // Now that we are done, clean up after ourselves spDestroyCompileRequest(compileRequest); |
