Exemple #1
0
        /// <summary>
        /// Constructs a new disassembler.
        /// </summary>
        /// <param name="methodBase">The target method.</param>
        /// <param name="sequencePointEnumerator">
        /// The associated sequence-point enumerator.
        /// </param>
        /// <param name="compilationStackLocation">The source location (optional).</param>
        public Disassembler(
            MethodBase methodBase,
            SequencePointEnumerator sequencePointEnumerator,
            CompilationStackLocation compilationStackLocation = null)
        {
            MethodBase = methodBase
                         ?? throw new ArgumentNullException(nameof(methodBase));
            MethodGenericArguments = MethodBase is MethodInfo
                ? MethodBase.GetGenericArguments()
                : Array.Empty <Type>();

            TypeGenericArguments = MethodBase.DeclaringType.GetGenericArguments();
            MethodBody           = MethodBase.GetMethodBody();
            if (MethodBody == null)
            {
                throw new NotSupportedException(string.Format(
                                                    ErrorMessages.NativeMethodNotSupported,
                                                    MethodBase.Name));
            }
            il           = MethodBody.GetILAsByteArray();
            instructions = ImmutableArray.CreateBuilder <ILInstruction>(il.Length);
            debugInformationEnumerator    = sequencePointEnumerator;
            this.compilationStackLocation = compilationStackLocation;
            CurrentLocation = new Method.MethodLocation(methodBase);
        }
Exemple #2
0
        /// <summary>
        /// Performs the actual (asynchronous) code generation.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <param name="isExternalRequest">
        /// True, if processing of this method was requested by a user.
        /// </param>
        /// <param name="compilationStackLocation">The source location.</param>
        /// <param name="detectedMethods">The set of newly detected methods.</param>
        /// <param name="generatedMethod">The resolved IR method.</param>
        internal void GenerateCodeInternal(
            MethodBase method,
            bool isExternalRequest,
            CompilationStackLocation compilationStackLocation,
            Dictionary <MethodBase, CompilationStackLocation> detectedMethods,
            out Method generatedMethod)
        {
            ILocation location = null;

            try
            {
                generatedMethod = Context.Declare(method, out bool created);
                if (!created & isExternalRequest)
                {
                    return;
                }
                location = generatedMethod;

                SequencePointEnumerator sequencePoints =
                    DebugInformationManager?.LoadSequencePoints(method)
                    ?? SequencePointEnumerator.Empty;
                var disassembler = new Disassembler(
                    method,
                    sequencePoints,
                    compilationStackLocation);
                var disassembledMethod = disassembler.Disassemble();

                using (var builder = generatedMethod.CreateBuilder())
                {
                    var codeGenerator = new CodeGenerator(
                        Frontend,
                        Context,
                        builder,
                        disassembledMethod,
                        compilationStackLocation,
                        detectedMethods);
                    codeGenerator.GenerateCode();
                    builder.Complete();
                }
                Verifier.Verify(generatedMethod);

                // Evaluate inlining heuristic to adjust method declaration
                Inliner.SetupInliningAttributes(
                    Context,
                    generatedMethod,
                    disassembledMethod);
            }
            catch (InternalCompilerException)
            {
                // If we already have an internal compiler exception, re-throw it.
                throw;
            }
            catch (Exception e)
            {
                // Wrap generic exceptions with location information.
                location ??= new Method.MethodLocation(method);
                throw location.GetException(e);
            }
        }
Exemple #3
0
 public ProcessingEntry(
     MethodBase method,
     CompilationStackLocation compilationStackLocation,
     CodeGenerationResult result)
 {
     Method = method;
     CompilationStackLocation = compilationStackLocation;
     Result = result;
 }
Exemple #4
0
        /// <summary>
        /// Creates a call instruction to the given method with the given arguments.
        /// </summary>
        /// <param name="method">The target method to invoke.</param>
        /// <param name="arguments">The call arguments.</param>
        private void CreateCall(
            MethodBase method,
            ref ValueList arguments)
        {
            var intrinsicContext = new InvocationContext(
                this,
                CompilationStackLocation.Append(Location),
                Block,
                Method,
                method,
                ref arguments);

            // Check for internal remappings first
            RemappedIntrinsics.RemapIntrinsic(ref intrinsicContext);

            // Early rejection for runtime-dependent methods
            VerifyNotRuntimeMethod(intrinsicContext.Method);

            // Handle device functions
            if (!Intrinsics.HandleIntrinsic(ref intrinsicContext, out var result))
            {
                var targetFunction = DeclareMethod(intrinsicContext.Method);

                result = Builder.CreateCall(
                    Location,
                    targetFunction,
                    ref arguments);
            }

            // Setup result
            if (result.IsValid && !result.Type.IsVoidType)
            {
                var flags = method.GetReturnType().IsUnsignedInt()
                    ? ConvertFlags.SourceUnsigned
                    : ConvertFlags.None;
                Block.Push(LoadOntoEvaluationStack(result, flags));
            }
        }