diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index ff1fb32ff..727c8c362 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -559,13 +559,40 @@ template<> void VMCheckReturn(VMFunction* func); template<> void VMCheckReturn(VMFunction* func); template<> void VMCheckReturn(VMFunction* func); template<> void VMCheckReturn(VMFunction* func); +template<> void VMCheckReturn(VMFunction* func); + +template +struct vm_decay_pointer_object +{ // convert any pointer to a type derived from DObject into a pointer to DObject, and any other to a pointer to void + using decayed = typename std::conditional::element_type>, + typename std::pointer_traits::template rebind, + typename std::pointer_traits::template rebind>::type; +}; + +template +struct vm_decay_pointer_void +{ // convert any pointer to a type derived from DObject into a pointer to DObject, and any other to a pointer to void + using decayed = typename std::pointer_traits::template rebind; +}; + +template +struct vm_decay_none +{ + using decayed = T; +}; + +template +using vm_pointer_decay = typename std::conditional, vm_decay_pointer_object, vm_decay_none>::type::decayed; + +template +using vm_pointer_decay_void = typename std::conditional, vm_decay_pointer_void, vm_decay_none>::type::decayed; template void VMValidateSignatureSingle(VMFunction* func, std::index_sequence) { VMCheckParamCount(func, sizeof...(Args)); - VMCheckReturn(func); - (VMCheckParam(func, I)...); + VMCheckReturn>(func); + (VMCheckParam>(func, I), ...); } void VMCallCheckResult(VMFunction* func, VMValue* params, int numparams, VMReturn* results, int numresults); @@ -573,17 +600,19 @@ void VMCallCheckResult(VMFunction* func, VMValue* params, int numparams, VMRetur template typename VMReturnTypeTrait::type VMCallSingle(VMFunction* func, Args... args) { - VMValidateSignature(func); + VMValidateSignatureSingle(func, std::make_index_sequence{}); VMValue params[] = { args... }; - RetVal resultval; VMReturn results(&resultval); + + vm_pointer_decay_void resultval; // convert any pointer to void + VMReturn results(&resultval); VMCallCheckResult(func, params, sizeof...(Args), &results, 1); - return resultval; + return (RetVal)resultval; } template -typename VMReturnTypeTrait::type VMCallSingle(VMFunction* func, Args... args) +typename VMReturnTypeTrait::type VMCallVoid(VMFunction* func, Args... args) { - VMValidateSignature(func); + VMValidateSignatureSingle(func, std::make_index_sequence{}); VMValue params[] = { args... }; VMCallCheckResult(func, params, sizeof...(Args), nullptr, 0); }