private static void HighLevelDebugFuncEvalHelperWithVariables(ref TypesAndValues param, ref LocalVariableSet arguments) { for (int i = 0; i < param.parameterValues.Length; i++) { unsafe { IntPtr input = arguments.GetAddressOfVarData(i + 1); byte * pInput = (byte *)input; fixed(byte *pParam = param.parameterValues[i]) { for (int j = 0; j < param.parameterValues[i].Length; j++) { pInput[j] = pParam[j]; } } } } // Obtain the target method address from the runtime IntPtr targetAddress = RuntimeAugments.RhpGetFuncEvalTargetAddress(); LocalVariableType[] returnAndArgumentTypes = new LocalVariableType[param.types.Length]; for (int i = 0; i < returnAndArgumentTypes.Length; i++) { returnAndArgumentTypes[i] = new LocalVariableType(param.types[i], false, false); } // Hard coding static here DynamicCallSignature dynamicCallSignature = new DynamicCallSignature(Internal.Runtime.CallConverter.CallingConvention.ManagedStatic, returnAndArgumentTypes, returnAndArgumentTypes.Length); // Invoke the target method Internal.Runtime.CallInterceptor.CallInterceptor.MakeDynamicCall(targetAddress, dynamicCallSignature, arguments); unsafe { // Box the return IntPtr input = arguments.GetAddressOfVarData(0); object returnValue = RuntimeAugments.RhBoxAny(input, (IntPtr)param.types[0].ToEETypePtr()); IntPtr returnValueHandlePointer = IntPtr.Zero; uint returnHandleIdentifier = 0; // The return value could be null if the target function returned null if (returnValue != null) { GCHandle returnValueHandle = GCHandle.Alloc(returnValue); returnValueHandlePointer = GCHandle.ToIntPtr(returnValueHandle); returnHandleIdentifier = RuntimeAugments.RhpRecordDebuggeeInitiatedHandle(returnValueHandlePointer); } ReturnToDebugger(returnHandleIdentifier, returnValueHandlePointer); } }
private static void HighLevelDebugFuncEvalHelperWithVariables(ref TypesAndValues param, ref LocalVariableSet arguments) { for (int i = 0; i < param.parameterValues.Length; i++) { arguments.SetVar <int>(i + 1, param.parameterValues[i]); } // Obtain the target method address from the runtime IntPtr targetAddress = RuntimeAugments.RhpGetFuncEvalTargetAddress(); LocalVariableType[] returnAndArgumentTypes = new LocalVariableType[param.types.Length]; for (int i = 0; i < returnAndArgumentTypes.Length; i++) { returnAndArgumentTypes[i] = new LocalVariableType(param.types[i], false, false); } // Hard coding static here DynamicCallSignature dynamicCallSignature = new DynamicCallSignature(Internal.Runtime.CallConverter.CallingConvention.ManagedStatic, returnAndArgumentTypes, returnAndArgumentTypes.Length); // Invoke the target method Internal.Runtime.CallInterceptor.CallInterceptor.MakeDynamicCall(targetAddress, dynamicCallSignature, arguments); unsafe { // Box the return IntPtr input = arguments.GetAddressOfVarData(0); object returnValue = RuntimeAugments.RhBoxAny(input, (IntPtr)param.types[0].ToEETypePtr()); GCHandle returnValueHandle = GCHandle.Alloc(returnValue); IntPtr returnValueHandlePointer = GCHandle.ToIntPtr(returnValueHandle); uint returnHandleIdentifier = RuntimeAugments.RhpRecordDebuggeeInitiatedHandle(returnValueHandlePointer); // Signal to the debugger the func eval completes FuncEvalCompleteCommand *funcEvalCompleteCommand = stackalloc FuncEvalCompleteCommand[1]; funcEvalCompleteCommand->commandCode = 0; funcEvalCompleteCommand->returnHandleIdentifier = returnHandleIdentifier; funcEvalCompleteCommand->returnAddress = (long)returnValueHandlePointer; IntPtr funcEvalCompleteCommandPointer = new IntPtr(funcEvalCompleteCommand); RuntimeAugments.RhpSendCustomEventToDebugger(funcEvalCompleteCommandPointer, Unsafe.SizeOf <FuncEvalCompleteCommand>()); } // debugger magic will make sure this function never returns, instead control will be transferred back to the point where the FuncEval begins }
private static void HighLevelDebugFuncEvalHelperWithVariables(ref int param, ref LocalVariableSet arguments) { // Hard coding the argument integer here! arguments.SetVar <int>(1, param); // Obtain the target method address from the runtime IntPtr targetAddress = RuntimeImports.RhpGetFuncEvalTargetAddress(); // Hard coding a single void return here LocalVariableType[] returnAndArgumentTypes = new LocalVariableType[2]; returnAndArgumentTypes[0] = new LocalVariableType(typeof(void).TypeHandle, false, false); returnAndArgumentTypes[1] = new LocalVariableType(typeof(int).TypeHandle, false, false); // Hard coding static here DynamicCallSignature dynamicCallSignature = new DynamicCallSignature(Internal.Runtime.CallConverter.CallingConvention.ManagedStatic, returnAndArgumentTypes, returnAndArgumentTypes.Length); // Invoke the target method Internal.Runtime.CallInterceptor.CallInterceptor.MakeDynamicCall(targetAddress, dynamicCallSignature, arguments); // Signal to the debugger the func eval completes IntPtr funcEvalCompleteCommandPointer; unsafe { FuncEvalCompleteCommand funcEvalCompleteCommand = new FuncEvalCompleteCommand { commandCode = 0 }; funcEvalCompleteCommandPointer = new IntPtr(&funcEvalCompleteCommand); } RuntimeImports.RhpSendCustomEventToDebugger(funcEvalCompleteCommandPointer, Unsafe.SizeOf <FuncEvalCompleteCommand>()); // debugger magic will make sure this function never returns, instead control will be transferred back to the point where the FuncEval begins }
private static void HighLevelDebugFuncEvalHelperWithVariables(ref TypesAndValues param, ref LocalVariableSet arguments) { // Offset begins with 1 because we always skip setting the return value before we call the function int offset = 1; if (param.thisObj != null) { // For constructors - caller does not pass the this pointer, instead, we constructed param.thisObj and pass it as the first argument arguments.SetVar <object>(offset, param.thisObj); offset++; } for (int i = 0; i < param.parameterValues.Length; i++) { unsafe { IntPtr input = arguments.GetAddressOfVarData(i + offset); byte * pInput = (byte *)input; fixed(byte *pParam = param.parameterValues[i]) { for (int j = 0; j < param.parameterValues[i].Length; j++) { pInput[j] = pParam[j]; } } } } // Obtain the target method address from the runtime IntPtr targetAddress = RuntimeAugments.RhpGetFuncEvalTargetAddress(); LocalVariableType[] returnAndArgumentTypes = new LocalVariableType[param.types.Length]; for (int i = 0; i < returnAndArgumentTypes.Length; i++) { returnAndArgumentTypes[i] = new LocalVariableType(param.types[i], false, false); } // Hard coding static here DynamicCallSignature dynamicCallSignature = new DynamicCallSignature(Internal.Runtime.CallConverter.CallingConvention.ManagedStatic, returnAndArgumentTypes, returnAndArgumentTypes.Length); // Invoke the target method Exception ex = null; try { Internal.Runtime.CallInterceptor.CallInterceptor.MakeDynamicCall(targetAddress, dynamicCallSignature, arguments); } catch (Exception e) { ex = e; } unsafe { bool isVoid = (RuntimeTypeHandle.Equals(param.types[0], typeof(void).TypeHandle)); object returnValue = null; IntPtr returnValueHandlePointer = IntPtr.Zero; uint returnHandleIdentifier = 0; if (ex != null) { returnValue = ex; } else if (param.thisObj != null) { // For constructors - the debugger would like to get 'this' back returnValue = param.thisObj; } else if (!isVoid) { IntPtr input = arguments.GetAddressOfVarData(0); returnValue = RuntimeAugments.RhBoxAny(input, param.types[0].Value); } // The return value could be null if the target function returned null if (returnValue != null) { GCHandle returnValueHandle = GCHandle.Alloc(returnValue); returnValueHandlePointer = GCHandle.ToIntPtr(returnValueHandle); returnHandleIdentifier = RuntimeAugments.RhpRecordDebuggeeInitiatedHandle(returnValueHandlePointer); } ReturnToDebuggerWithReturn(returnHandleIdentifier, returnValueHandlePointer, ex != null); } }
private unsafe static void InvokeFunction(ref InvokeFunctionData invokeFunctionData, ref LocalVariableSet arguments) { // Offset begins with 1 because we always skip setting the return value before we call the function int offset = 1; if (invokeFunctionData.thisObj != null) { // For constructors - caller does not pass the this pointer, instead, we constructed param.thisObj and pass it as the first argument arguments.SetVar <object>(offset, invokeFunctionData.thisObj); offset++; } for (int i = 0; i < invokeFunctionData.parameterValues.Length; i++) { IntPtr input = arguments.GetAddressOfVarData(i + offset); byte * pInput = (byte *)input; fixed(byte *pParam = invokeFunctionData.parameterValues[i]) { for (int j = 0; j < invokeFunctionData.parameterValues[i].Length; j++) { pInput[j] = pParam[j]; } } } // Obtain the target method address from the runtime IntPtr targetAddress = RuntimeAugments.RhpGetFuncEvalTargetAddress(); LocalVariableType[] returnAndArgumentTypes = new LocalVariableType[invokeFunctionData.types.Length]; for (int i = 0; i < returnAndArgumentTypes.Length; i++) { returnAndArgumentTypes[i] = new LocalVariableType(invokeFunctionData.types[i], false, false); } DynamicCallSignature dynamicCallSignature = new DynamicCallSignature(invokeFunctionData.callingConvention, returnAndArgumentTypes, returnAndArgumentTypes.Length); // Invoke the target method Exception ex = null; try { Internal.Runtime.CallInterceptor.CallInterceptor.MakeDynamicCall(targetAddress, dynamicCallSignature, arguments); } catch (Exception e) { ex = e; } bool isVoid = (RuntimeTypeHandle.Equals(invokeFunctionData.types[0], typeof(void).TypeHandle)); object returnValue = null; if (ex != null) { returnValue = ex; } else if (invokeFunctionData.thisObj != null) { // For constructors - the debugger would like to get 'this' back returnValue = invokeFunctionData.thisObj; } else if (!isVoid) { IntPtr input = arguments.GetAddressOfVarData(0); returnValue = RuntimeAugments.RhBoxAny(input, invokeFunctionData.types[0].Value); } // Note that the return value could be null if the target function returned null invokeFunctionData.result = new FuncEvalResult(returnValue, ex != null); }