private unsafe static void HighLevelDebugFuncEvalHelper() { uint parameterBufferSize = RuntimeAugments.RhpGetFuncEvalParameterBufferSize(); IntPtr writeParameterCommandPointer; IntPtr parameterBufferPointer; byte *parameterBuffer = stackalloc byte[(int)parameterBufferSize]; parameterBufferPointer = new IntPtr(parameterBuffer); WriteParameterCommand writeParameterCommand = new WriteParameterCommand { commandCode = 1, bufferAddress = parameterBufferPointer.ToInt64() }; writeParameterCommandPointer = new IntPtr(&writeParameterCommand); RuntimeAugments.RhpSendCustomEventToDebugger(writeParameterCommandPointer, Unsafe.SizeOf <WriteParameterCommand>()); // .. debugger magic ... the debuggerBuffer will be filled with parameter data FuncEvalMode mode = (FuncEvalMode)RuntimeAugments.RhpGetFuncEvalMode(); switch (mode) { case FuncEvalMode.RegularFuncEval: RegularFuncEval(parameterBuffer, parameterBufferSize); break; case FuncEvalMode.NewStringWithLength: NewStringWithLength(parameterBuffer, parameterBufferSize); break; default: Debug.Assert(false, "Debugger provided an unexpected func eval mode."); break; } }
private static void HighLevelDebugFuncEvalHelper() { int integerParameterValue = 0; uint parameterBufferSize = RuntimeImports.RhpGetFuncEvalParameterBufferSize(); IntPtr writeParameterCommandPointer; IntPtr debuggerBufferPointer; unsafe { byte *debuggerBufferRawPointer = stackalloc byte[(int)parameterBufferSize]; debuggerBufferPointer = new IntPtr(debuggerBufferRawPointer); WriteParameterCommand writeParameterCommand = new WriteParameterCommand { commandCode = 1, bufferAddress = debuggerBufferPointer.ToInt64() }; writeParameterCommandPointer = new IntPtr(&writeParameterCommand); } RuntimeImports.RhpSendCustomEventToDebugger(writeParameterCommandPointer, Unsafe.SizeOf <WriteParameterCommand>()); // .. debugger magic ... the debuggerBuffer will be filled with parameter data unsafe { integerParameterValue = Unsafe.Read <int>(debuggerBufferPointer.ToPointer()); } // Hard coding a single argument of type int here LocalVariableType[] argumentTypes = new LocalVariableType[2]; argumentTypes[0] = new LocalVariableType(typeof(void).TypeHandle, false, false); argumentTypes[1] = new LocalVariableType(typeof(int).TypeHandle, false, false); LocalVariableSet.SetupArbitraryLocalVariableSet <int>(HighLevelDebugFuncEvalHelperWithVariables, ref integerParameterValue, argumentTypes); }
private static void HighLevelDebugFuncEvalHelper() { uint parameterBufferSize = RuntimeAugments.RhpGetFuncEvalParameterBufferSize(); IntPtr writeParameterCommandPointer; IntPtr debuggerBufferPointer; unsafe { byte *debuggerBufferRawPointer = stackalloc byte[(int)parameterBufferSize]; debuggerBufferPointer = new IntPtr(debuggerBufferRawPointer); WriteParameterCommand writeParameterCommand = new WriteParameterCommand { commandCode = 1, bufferAddress = debuggerBufferPointer.ToInt64() }; writeParameterCommandPointer = new IntPtr(&writeParameterCommand); RuntimeAugments.RhpSendCustomEventToDebugger(writeParameterCommandPointer, Unsafe.SizeOf <WriteParameterCommand>()); // .. debugger magic ... the debuggerBuffer will be filled with parameter data TypesAndValues typesAndValues = new TypesAndValues(); uint trash; uint parameterCount; uint parameterValue; uint eeTypeCount; ulong eeType; uint offset = 0; NativeReader reader = new NativeReader(debuggerBufferRawPointer, parameterBufferSize); offset = reader.DecodeUnsigned(offset, out trash); // The VertexSequence always generate a length, I don't really need it. offset = reader.DecodeUnsigned(offset, out parameterCount); typesAndValues.parameterValues = new int[parameterCount]; for (int i = 0; i < parameterCount; i++) { offset = reader.DecodeUnsigned(offset, out parameterValue); typesAndValues.parameterValues[i] = (int)parameterValue; } offset = reader.DecodeUnsigned(offset, out eeTypeCount); for (int i = 0; i < eeTypeCount; i++) { // TODO: Stuff these eeType values into the external reference table offset = reader.DecodeUnsignedLong(offset, out eeType); } TypeSystemContext typeSystemContext = TypeSystemContextFactory.Create(); bool hasThis; TypeDesc[] parameters; bool[] parametersWithGenericDependentLayout; bool result = TypeLoaderEnvironment.Instance.GetCallingConverterDataFromMethodSignature_NativeLayout_Debugger(typeSystemContext, RuntimeSignature.CreateFromNativeLayoutSignatureForDebugger(offset), Instantiation.Empty, Instantiation.Empty, out hasThis, out parameters, out parametersWithGenericDependentLayout, reader); typesAndValues.types = new RuntimeTypeHandle[parameters.Length]; bool needToDynamicallyLoadTypes = false; for (int i = 0; i < typesAndValues.types.Length; i++) { if (!parameters[i].RetrieveRuntimeTypeHandleIfPossible()) { needToDynamicallyLoadTypes = true; break; } typesAndValues.types[i] = parameters[i].GetRuntimeTypeHandle(); } if (needToDynamicallyLoadTypes) { TypeLoaderEnvironment.Instance.RunUnderTypeLoaderLock(() => { typeSystemContext.FlushTypeBuilderStates(); GenericDictionaryCell[] cells = new GenericDictionaryCell[parameters.Length]; for (int i = 0; i < cells.Length; i++) { cells[i] = GenericDictionaryCell.CreateTypeHandleCell(parameters[i]); } IntPtr[] eetypePointers; TypeBuilder.ResolveMultipleCells(cells, out eetypePointers); for (int i = 0; i < parameters.Length; i++) { typesAndValues.types[i] = ((EEType *)eetypePointers[i])->ToRuntimeTypeHandle(); } }); } TypeSystemContextFactory.Recycle(typeSystemContext); LocalVariableType[] argumentTypes = new LocalVariableType[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { // TODO: What these false really means? Need to make sure our format contains those information argumentTypes[i] = new LocalVariableType(typesAndValues.types[i], false, false); } LocalVariableSet.SetupArbitraryLocalVariableSet <TypesAndValues>(HighLevelDebugFuncEvalHelperWithVariables, ref typesAndValues, argumentTypes); } }