コード例 #1
0
ファイル: DebugFuncEval.cs プロジェクト: mskvortsov/corert
        private unsafe static FuncEvalResult CallParameterizedFunctionOrNewParameterizedObject(ref long myFuncEvalId, byte *parameterBuffer, uint parameterBufferSize, bool isConstructor)
        {
            InvokeFunctionData invokeFunctionData = new InvokeFunctionData();

            LowLevelNativeFormatReader reader = new LowLevelNativeFormatReader(parameterBuffer, parameterBufferSize);

            myFuncEvalId = s_funcEvalId = (long)reader.GetUnsignedLong();
            uint parameterCount = reader.GetUnsigned();

            invokeFunctionData.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;
                }
                invokeFunctionData.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
                );

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

            for (int i = 0; i < invokeFunctionData.types.Length; i++)
            {
                invokeFunctionData.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(invokeFunctionData.types[i], false, false);
            }

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

            LocalVariableSet.SetupArbitraryLocalVariableSet <InvokeFunctionData>(InvokeFunction, ref invokeFunctionData, argumentTypes);

            return(invokeFunctionData.result);
        }
コード例 #2
0
ファイル: DebugFuncEval.cs プロジェクト: kevingosse/corert
        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);
        }