diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-10-04 13:54:25 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-04 13:54:25 -0700 |
| commit | 54f016e7ef36b7505bf47d188cf4b7e1fdc443a4 (patch) | |
| tree | f8a385c8a3bbac807c2c0d08a9b1e4cd208db95c /source/slang/vm.cpp | |
| parent | 8a0ebb9fa25fd44def17b03b3f8aa1a33ad77940 (diff) | |
IR: overhaul IR design/implementation (#195)
* IR: overhaul IR design/implementation
Closes #192
Closes #188
This is a major overhaul of how the IR is implemented, with the primary goal of just using the AST-level type representation as the IR's type representation, rather than inventing an entire shadow set of types (as captured in issue #192).
One consequence of this choice is that types in the IR are no longer explicit "instructions" and are not represented as ordinary operands (so a bunch of `+ 1` cases end up going away when enumerating ordinary operands).
Along the way I also got rid of the embedded IDs in the IR (issue #188) because this wasn't too hard to deal with at the same time.
Another related change was to split the `IRValue` and `IRInst` cases, so that there are values that are not also instructions. Non-instruction values are now used to represent literals, references to declarations, and would eventually be used for an `undef` value if we need one. IR functions, global variables, and basic blocks are all values (because they can appear as operands), but not instructions.
The main benefit of this approach is that the top-level structure of a bytecode (BC) module is much simpler to understand and walk, and BC-level types are represented much more directly (such that we could conceivably use them for reflection soon).
* fixup: 64-bit build fix
* fixup: try to silence clang's pedantic dependent-type errors
* fixup: bug in VM loading of constants
Diffstat (limited to 'source/slang/vm.cpp')
| -rw-r--r-- | source/slang/vm.cpp | 616 |
1 files changed, 360 insertions, 256 deletions
diff --git a/source/slang/vm.cpp b/source/slang/vm.cpp index 65ecefc01..d3e44a947 100644 --- a/source/slang/vm.cpp +++ b/source/slang/vm.cpp @@ -11,28 +11,43 @@ namespace Slang { -// Representation of a type during VM execution -struct VMTypeImpl +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 VMType + +struct VMVal { - VMTypeImpl* impl; + VMValImpl* impl; - UInt getSize() { return impl->size; } - UInt getAlignment() { return impl->alignment; } + 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; - uint32_t addressSpace; }; struct VMReg @@ -47,20 +62,20 @@ struct VMReg struct VMConst { // Type of the constant - VMType type; + VMType type; // Operand address to use void* ptr; }; -struct VMFrame; +struct VMModule; // Information about a function after it has been // loaded into the VM. struct VMFunc { // The parent module that this function belongs to - VMFrame* module; + VMModule* module; BCFunc* bcFunc; VMReg* regs; @@ -84,8 +99,14 @@ struct VMFrame // Registers are stored after this point. }; -struct VMModule : VMFunc +struct VM; + +struct VMModule { + BCModule* bcModule; + VM* vm; + void** symbols; + VMType* types; }; UInt decodeUInt(BCOp** ioPtr) @@ -93,13 +114,28 @@ UInt decodeUInt(BCOp** ioPtr) BCOp* ptr = *ioPtr; UInt value = *ptr++; - if( value >= 128 ) + if( value < 128 ) { - SLANG_UNEXPECTED("deal with this later"); + *ioPtr = ptr; + return value; } - *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) @@ -194,9 +230,15 @@ 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, - VMFrame* vmModuleInstance); + VMModule* vmModule); struct VMSizeAlign { @@ -231,9 +273,30 @@ VMSizeAlign getVMSymbolSize(BCSymbol* symbol) 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, - VMFrame* vmModuleInstance) + VMModule* vmModule) { UInt regCount = bcFunc->regCount; UInt constCount = bcFunc->constCount; @@ -245,7 +308,7 @@ VMFunc* loadVMFunc( VMReg* vmRegs = (VMReg*) (vmFunc + 1); VMConst* vmConsts = (VMConst*) (vmRegs + regCount); - vmFunc->module = vmModuleInstance; + vmFunc->module = vmModule; vmFunc->bcFunc = bcFunc; vmFunc->regs = vmRegs; vmFunc->consts = vmConsts; @@ -254,31 +317,14 @@ VMFunc* loadVMFunc( for( UInt rr = 0; rr < regCount; ++rr ) { BCReg* bcReg = &bcFunc->regs[rr]; - auto typeGlobalID = bcReg->typeGlobalID; - - // HACK: when we are loading a module itself, we might - // not yet know the size for the things it defines - // (since the module itself might define the type of - // one of its symbols), so for now we hack it and - // assume everything at module level is 16 bytes or less. - // - // TODO: this also seems like it will cause problems - // in other contexts (any time the type of a register - // would depend on an earlier instruction in the same - // scope) so this needs careful thought. - VMType vmType = { nullptr }; - UInt regSize = 16; - UInt regAlign = 8; - - if (vmModuleInstance) - { - // We expect the type to come from the outer module, so - // that we can allocate space for it as we go. - vmType = *(VMType*)getRegPtrImpl(vmModuleInstance, typeGlobalID); + auto bcTypeID = bcReg->typeID; - regSize = vmType.getSize(); - regAlign = vmType.getAlignment(); - } + // 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); @@ -292,10 +338,32 @@ VMFunc* loadVMFunc( for( UInt cc = 0; cc < constCount; ++cc ) { - auto globalID = bcFunc->consts[cc].globalID; - auto globalPtr = getRegPtrImpl(vmModuleInstance, globalID); - vmFunc->consts[cc].ptr = globalPtr; - vmFunc->consts[cc].type = vmModuleInstance->func->regs[globalID].type; + 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; @@ -368,7 +436,7 @@ void dumpVMFrame(VMFrame* vmFrame) case kIROp_PtrType: { - fprintf(stderr, ": Ptr<???> = 0x%p", *(void**)regData); + fprintf(stderr, ": Ptr<?> = [%p]", *(void**)regData); } break; @@ -416,7 +484,186 @@ struct VMThread void resumeThread( VMThread* vmThread); -VMFrame* loadVMModuleInstance( +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_Int32Type: + case kIROp_UInt32Type: + case kIROp_Float32Type: + size = 4; + break; + + case kIROp_FuncType: + case kIROp_PtrType: + case kIROp_readWriteStructuredBufferType: + case kIROp_structuredBufferType: + size = sizeof(void*); + break; + + default: + SLANG_UNIMPLEMENTED_X("type sizing"); + 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 = 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); + } + + SLANG_UNEXPECTED("unimplemented"); + 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_global_var: + { + 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_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) @@ -425,45 +672,63 @@ VMFrame* loadVMModuleInstance( BCModule* bcModule = bcHeader->module; - UInt vmModuleSize = sizeof(VMModule) + bcModule->regCount * sizeof(VMReg); + UInt symbolCount = bcModule->symbolCount; + UInt typeCount = bcModule->typeCount; - VMModule* vmModule = (VMModule*) loadVMFunc(bcModule, nullptr); + UInt vmModuleSize = sizeof(VMModule) + + symbolCount * sizeof(void*) + + typeCount * sizeof(VMType); - // Create a frame to store the loaded symbols, and execute it - // to initialize them. - VMFrame* vmModuleInstance = createFrame(vmModule); - vmModuleInstance->parent = nullptr; - vmModule->module = vmModuleInstance; + VMModule* vmModule = (VMModule*)malloc(vmModuleSize); + memset(vmModule, 0, vmModuleSize); + void** vmSymbols = (void**)(vmModule + 1); + VMType* vmTypes = (VMType*)(vmSymbols + symbolCount); - VMThread thread; - thread.frame = vmModuleInstance; + vmModule->bcModule = bcModule; + vmModule->vm = vm; + vmModule->symbols = vmSymbols; + vmModule->types = vmTypes; - resumeThread(&thread); + // 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 vmModuleInstance; + return vmModule; } void* findGlobalSymbolPtr( - VMFrame* moduleInstance, + VMModule* module, char const* name) { // Okay, we need to search through the available - // "registers" looking for one that gives us a - // name match. - // - BCFunc* bcFunc = moduleInstance->func->bcFunc; - UInt regCount = bcFunc->regCount; - for (UInt rr = 0; rr < regCount; ++rr) + // 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) { - BCReg* bcReg = &bcFunc->regs[rr]; + BCSymbol* bcSymbol = bcModule->symbols[ss]; - char const* symbolName = bcReg->name; + char const* symbolName = bcSymbol->name; if (!symbolName) continue; if(strcmp(symbolName, name) == 0) - return getRegPtrImpl(moduleInstance, rr); + return getGlobalPtr(module, ss); } return nullptr; @@ -516,182 +781,11 @@ void resumeThread( auto op = (IROp) decodeUInt(&ip); switch( op ) { - case kIROp_TypeType: - { - // The type of types - Int argCount = decodeUInt(&ip); - void* arg0Ptr = decodeOperandPtr<void>(frame, &ip); - VMType* destPtr = decodeOperandPtr<VMType>(frame, &ip); - - auto typeImpl = new VMTypeImpl(); - typeImpl->op = op; - typeImpl->size = sizeof(VMType); - typeImpl->alignment = alignof(VMType); - - VMType type = { typeImpl }; - *destPtr = type; - } - break; - - case kIROp_BlockType: - case kIROp_Int32Type: - case kIROp_UInt32Type: - case kIROp_Float32Type: - case kIROp_BoolType: - case kIROp_VoidType: - case kIROp_FuncType: // TODO: we should in principle handle function types here - { - // Case to handle types without arguments. - UInt argCount = decodeUInt(&ip); - for( UInt aa = 0; aa < argCount; ++aa ) - { - void* argPtr = decodeOperandPtr<void>(frame, &ip); - } - VMType* destPtr = decodeOperandPtr<VMType>(frame, &ip); - - auto typeImpl = new VMTypeImpl(); - typeImpl->op = op; - - UInt size = 1; - UInt align = 0; - switch (op) - { - case kIROp_BlockType: size = sizeof(void*); break; - case kIROp_Int32Type: size = sizeof(int32_t); break; - case kIROp_UInt32Type: size = sizeof(uint32_t); break; - case kIROp_Float32Type: size = sizeof(float); break; - case kIROp_BoolType: size = sizeof(bool); break; - case kIROp_VoidType: size = 0; align = 1; break; - default: - break; - } - if (!align) align = size; - typeImpl->size = size; - typeImpl->alignment = align; - - VMType type = { typeImpl }; - *destPtr = type; - } - break; - - case kIROp_PtrType: - { - // Case to handle types without arguments. - UInt argCount = decodeUInt(&ip); - VMType* typeTypePtr = decodeOperandPtr<VMType>(frame, &ip); - VMType baseType = decodeOperand<VMType>(frame, &ip); - int32_t addressSpace = decodeOperand<int32_t>(frame, &ip); - VMType* destPtr = decodeOperandPtr<VMType>(frame, &ip); - - - - auto typeImpl = new VMPtrTypeImpl(); - typeImpl->op = op; - typeImpl->size = sizeof(void*); - typeImpl->alignment = alignof(void*); - typeImpl->base = baseType; - typeImpl->addressSpace = addressSpace; - - VMType type = { typeImpl }; - *destPtr = type; - } - break; - - case kIROp_readWriteStructuredBufferType: - case kIROp_structuredBufferType: - { - // Case to handle types without arguments. - UInt argCount = decodeUInt(&ip); - VMType* typeTypePtr = decodeOperandPtr<VMType>(frame, &ip); - VMType baseType = decodeOperand<VMType>(frame, &ip); - VMType* destPtr = decodeOperandPtr<VMType>(frame, &ip); - - - // TODO: give these their own representations! - auto typeImpl = new VMPtrTypeImpl(); - typeImpl->op = op; - typeImpl->base = baseType; - typeImpl->size = sizeof(void*); - typeImpl->alignment = sizeof(void*); - - VMType type = { typeImpl }; - *destPtr = type; - } - break; - - - case kIROp_IntLit: - { - VMType type = decodeOperand<VMType>(frame, &ip); - UInt uVal = decodeUInt(&ip); - void* destPtr = decodeOperandPtr<void>(frame, &ip); - - switch( type.impl->op ) - { - case kIROp_Int32Type: - *(int32_t*)destPtr = int32_t(uVal); - break; - - case kIROp_UInt32Type: - *(uint32_t*)destPtr = uint32_t(uVal); - break; - - default: - SLANG_UNEXPECTED("integer type"); - break; - } - - } - break; - - case kIROp_FloatLit: - { - VMType type = decodeOperand<VMType>(frame, &ip); - - static const UInt size = sizeof(IRFloatingPointValue); - IRFloatingPointValue value; - memcpy(&value, ip, size); - ip += size; - void* destPtr = decodeOperandPtr<void>(frame, &ip); - - switch( type.impl->op ) - { - case kIROp_Float32Type: - *(float*)destPtr = float(value); - break; - - default: - SLANG_UNEXPECTED("float type"); - break; - } - } - break; - - case kIROp_boolConst: - { - bool val = (*ip++) != 0; - bool* destPtr = decodeOperandPtr<bool>(frame, &ip); - *destPtr = val; - } - break; - - case kIROp_Func: - { - UInt nestedID = decodeUInt(&ip); - void* destPtr = decodeOperandPtr<void>(frame, &ip); - - BCSymbol* bcSymbol = frame->func->bcFunc->nestedSymbols[nestedID]; - BCFunc* bcFunc = (BCFunc*)bcSymbol; - VMFunc* vmFunc = loadVMFunc(bcFunc, frame->func->module); - - *(VMFunc**)destPtr = vmFunc; - } - break; - 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 ) @@ -714,10 +808,17 @@ void resumeThread( case kIROp_Store: { // An ordinary memory store - VMType type = decodeOperand<VMType>(frame, &ip); + 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; @@ -725,7 +826,7 @@ void resumeThread( case kIROp_Load: { // An ordinary memory store - VMType type = decodeOperand<VMType>(frame, &ip); + VMType type = decodeType(frame, &ip); void* src = decodeOperand<void*>(frame, &ip); void* dest = decodeOperandPtr<void>(frame, &ip); @@ -735,6 +836,7 @@ void resumeThread( case kIROp_BufferLoad: { + VMType type = decodeType(frame, &ip); UInt argCount = decodeUInt(&ip); void* argPtrs[16] = { 0 }; for( UInt aa = 0; aa < argCount; ++aa ) @@ -745,9 +847,8 @@ void resumeThread( void* dest = decodeOperandPtr<void>(frame, &ip); - VMType type = *(VMType*)argPtrs[0]; - char* bufferData = *(char**)argPtrs[1]; - uint32_t index = *(uint32_t*)argPtrs[2]; + char* bufferData = *(char**)argPtrs[0]; + uint32_t index = *(uint32_t*)argPtrs[1]; auto size = type.getSize(); char* elementData = bufferData + index*size; @@ -757,9 +858,9 @@ void resumeThread( case kIROp_BufferStore: { + VMType resultType = decodeType(frame, &ip); UInt argCount = decodeUInt(&ip); - VMType* resultTypePtr = decodeOperandPtr<VMType>(frame, &ip); char* bufferData = decodeOperand<char*>(frame, &ip); uint32_t index = decodeOperand<uint32_t>(frame, &ip); @@ -774,8 +875,10 @@ void resumeThread( break; case kIROp_Call: { + VMType type = decodeType(frame, &ip); UInt operandCount = decodeUInt(&ip); - VMType type = decodeOperand<VMType>(frame, &ip); + + // First operand is the callee function VMFunc* func = decodeOperand<VMFunc*>(frame, &ip); // Okay, we need to create a frame to prepare the call @@ -784,7 +887,7 @@ void resumeThread( // Remaining arguments should populate the // first N registers of the callee - UInt argCount = operandCount - 2; + UInt argCount = operandCount - 1; for( UInt aa = 0; aa < argCount; ++aa ) { void* argPtr = decodeOperandPtr<void>(frame, &ip); @@ -836,8 +939,8 @@ void resumeThread( case kIROp_ReturnVal: { + VMType instType = decodeType(frame, &ip); UInt argCount = decodeUInt(&ip); - void* typePtr = decodeOperandPtr<void>(frame, &ip); void* argPtr = decodeOperandPtr<void>(frame, &ip); VMFrame* oldFrame = frame; @@ -868,8 +971,8 @@ void resumeThread( // 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* typePtr = decodeOperandPtr<void>(frame, &ip); Int destinationBlock = decodeSInt(&ip); for( UInt aa = 2; aa < argCount; ++aa ) { @@ -892,8 +995,8 @@ void resumeThread( // 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* typePtr = decodeOperandPtr<void>(frame, &ip); bool* condition = decodeOperandPtr<bool>(frame, &ip); Int trueBlockID = decodeSInt(&ip); Int falseBlockID = decodeSInt(&ip); @@ -917,9 +1020,9 @@ void resumeThread( // 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 }; - VMType resultType = decodeOperand<VMType>(frame, &ip); auto leftOpnd = decodeOperandPtrAndType(frame, &ip); auto type = leftOpnd.type; auto leftPtr = leftOpnd.ptr; @@ -942,8 +1045,8 @@ void resumeThread( case kIROp_Mul: { + VMType type = decodeType(frame, &ip); UInt argCount = decodeUInt(&ip); - VMType type = decodeOperand<VMType>(frame, &ip); void* leftPtr = decodeOperandPtr<void>(frame, &ip); void* rightPtr = decodeOperandPtr<void>(frame, &ip); @@ -964,8 +1067,8 @@ void resumeThread( case kIROp_Sub: { + VMType type = decodeType(frame, &ip); UInt argCount = decodeUInt(&ip); - VMType type = decodeOperand<VMType>(frame, &ip); void* leftPtr = decodeOperandPtr<void>(frame, &ip); void* rightPtr = decodeOperandPtr<void>(frame, &ip); @@ -989,6 +1092,7 @@ void resumeThread( // 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 ) @@ -1039,7 +1143,7 @@ SLANG_API void* SlangVMModule_findGlobalSymbolPtr( char const* name) { return (SlangVMFunc*) Slang::findGlobalSymbolPtr( - (Slang::VMFrame*) module, + (Slang::VMModule*) module, name); } |
