예제 #1
0
        private unsafe static void CallParameterizedFunctionOrNewParameterizedObject(byte *parameterBuffer, uint parameterBufferSize, bool isConstructor)
        {
            TypesAndValues typesAndValues = new TypesAndValues();

            LowLevelNativeFormatReader reader = new LowLevelNativeFormatReader(parameterBuffer, parameterBufferSize);
            uint parameterCount = reader.GetUnsigned();

            typesAndValues.parameterValues = new byte[parameterCount][];
            for (int i = 0; i < parameterCount; i++)
            {
                uint   parameterValueSize = reader.GetUnsigned();
                byte[] parameterValue     = new byte[parameterValueSize];
                for (int j = 0; j < parameterValueSize; j++)
                {
                    uint parameterByte = reader.GetUnsigned();
                    parameterValue[j] = (byte)parameterByte;
                }
                typesAndValues.parameterValues[i] = parameterValue;
            }
            ulong[] debuggerPreparedExternalReferences;
            BuildDebuggerPreparedExternalReferences(reader, out debuggerPreparedExternalReferences);


            bool hasThis;

            TypeDesc[] parameters;
            bool[]     parametersWithGenericDependentLayout;
            bool       result = TypeSystemHelper.CallingConverterDataFromMethodSignature(
                reader,
                debuggerPreparedExternalReferences,
                out hasThis,
                out parameters,
                out parametersWithGenericDependentLayout
                );

            typesAndValues.types = new RuntimeTypeHandle[parameters.Length];

            for (int i = 0; i < typesAndValues.types.Length; i++)
            {
                typesAndValues.types[i] = parameters[i].GetRuntimeTypeHandle();
            }

            LocalVariableType[] argumentTypes = new LocalVariableType[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                // TODO, FuncEval, what these false really means? Need to make sure our format contains those information
                argumentTypes[i] = new LocalVariableType(typesAndValues.types[i], false, false);
            }

            if (isConstructor)
            {
                // TODO, FuncEval, deal with Nullable objects
                typesAndValues.thisObj = RuntimeAugments.RawNewObject(typesAndValues.types[1]);
            }

            LocalVariableSet.SetupArbitraryLocalVariableSet <TypesAndValues>(HighLevelDebugFuncEvalHelperWithVariables, ref typesAndValues, argumentTypes);
        }
예제 #2
0
        private unsafe static void CallParameterizedFunctionOrNewParameterizedObject(byte *parameterBuffer, uint parameterBufferSize, bool isConstructor)
        {
            TypesAndValues typesAndValues = new TypesAndValues();
            uint           offset         = 0;

            NativeReader reader = new NativeReader(parameterBuffer, parameterBufferSize);
            uint         parameterCount;

            offset = reader.DecodeUnsigned(offset, out parameterCount);
            typesAndValues.parameterValues = new byte[parameterCount][];
            for (int i = 0; i < parameterCount; i++)
            {
                uint parameterValueSize;
                offset = reader.DecodeUnsigned(offset, out parameterValueSize);
                byte[] parameterValue = new byte[parameterValueSize];
                for (int j = 0; j < parameterValueSize; j++)
                {
                    uint parameterByte;
                    offset            = reader.DecodeUnsigned(offset, out parameterByte);
                    parameterValue[j] = (byte)parameterByte;
                }
                typesAndValues.parameterValues[i] = parameterValue;
            }
            ulong[] debuggerPreparedExternalReferences;
            offset = BuildDebuggerPreparedExternalReferences(reader, offset, out debuggerPreparedExternalReferences);

            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, debuggerPreparedExternalReferences);

            typesAndValues.types = new RuntimeTypeHandle[parameters.Length];

            for (int i = 0; i < typesAndValues.types.Length; i++)
            {
                typesAndValues.types[i] = parameters[i].GetRuntimeTypeHandle();
            }

            TypeSystemContextFactory.Recycle(typeSystemContext);

            LocalVariableType[] argumentTypes = new LocalVariableType[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                // TODO, FuncEval, what these false really means? Need to make sure our format contains those information
                argumentTypes[i] = new LocalVariableType(typesAndValues.types[i], false, false);
            }

            if (isConstructor)
            {
                typesAndValues.thisObj = RuntimeAugments.NewObject(typesAndValues.types[1]);
            }

            LocalVariableSet.SetupArbitraryLocalVariableSet <TypesAndValues>(HighLevelDebugFuncEvalHelperWithVariables, ref typesAndValues, argumentTypes);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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
        }
예제 #5
0
        private unsafe static void RegularFuncEval(byte *parameterBuffer, uint parameterBufferSize)
        {
            TypesAndValues typesAndValues = new TypesAndValues();

            uint  trash;
            uint  parameterCount;
            uint  parameterValueSize;
            uint  eeTypeCount;
            ulong eeType;
            uint  offset = 0;

            NativeReader reader = new NativeReader(parameterBuffer, 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 byte[parameterCount][];
            for (int i = 0; i < parameterCount; i++)
            {
                offset = reader.DecodeUnsigned(offset, out parameterValueSize);
                byte[] parameterValue = new byte[parameterValueSize];
                for (int j = 0; j < parameterValueSize; j++)
                {
                    uint parameterByte;
                    offset            = reader.DecodeUnsigned(offset, out parameterByte);
                    parameterValue[j] = (byte)parameterByte;
                }
                typesAndValues.parameterValues[i] = parameterValue;
            }
            offset = reader.DecodeUnsigned(offset, out eeTypeCount);
            ulong[] debuggerPreparedExternalReferences = new ulong[eeTypeCount];
            for (int i = 0; i < eeTypeCount; i++)
            {
                offset = reader.DecodeUnsignedLong(offset, out eeType);
                debuggerPreparedExternalReferences[i] = 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, debuggerPreparedExternalReferences);

            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, FuncEval, 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);
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
            }
        }