Пример #1
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters)
        {
            SymbolOperand callTargetOperand = this.GetInternalAllocateStringCallTarget(typeSystem);
            SymbolOperand methodTableOperand = new SymbolOperand(BuiltInSigType.IntPtr, StringClassMethodTableSymbolName);
            Operand lengthOperand = context.Operand1;
            Operand result = context.Result;

            context.SetInstruction(IR.Instruction.CallInstruction, result, callTargetOperand, methodTableOperand, lengthOperand);
        }
        private Operand InsertLoadBeforeInstruction(Context context, string symbolName, SigType type)
        {
            Context before = context.InsertBefore();
            Operand result = this.methodCompiler.CreateTemporary(type);
            Operand op = new SymbolOperand(type, symbolName);

            before.SetInstruction(Instruction.Get(OpCode.Ldc_i4), result, op);

            return result;
        }
        /// <summary>
        /// Calls the specified target.
        /// </summary>
        /// <param name="symbolOperand">The symbol operand.</param>
        public void Call(SymbolOperand symbolOperand)
        {
            linker.Link(
                LinkType.RelativeOffset | LinkType.NativeI4,
                compiler.Method.ToString(),
                (int)(codeStream.Position - codeStreamBasePosition),
                (int)(codeStream.Position - codeStreamBasePosition) + 4,
                symbolOperand.Name,
                IntPtr.Zero
            );

            codeStream.Position += 4;
        }
Пример #4
0
        /// <summary>
        /// Visitation function for Ldstr instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Ldstr(Context context)
        {
            /*
             * This requires a special memory layout for strings as they are interned by the compiler
             * into the generated image. This won't work this way forever: As soon as we'll support
             * a real AppDomain and real string interning, this code will have to go away and will
             * be replaced by a proper VM call.
             *
             */

            IAssemblyLinker linker = methodCompiler.Linker;
            IMetadataModule assembly = methodCompiler.Assembly;

            string referencedString = assembly.Metadata.ReadUserString(context.TokenType);

            string symbolName = @"$ldstr$" + assembly.Name + "$String" + context.TokenType.ToString("x");

            if (!linker.HasSymbol(symbolName))
            {
                // HACK: These strings should actually go into .rodata, but we can't link that right now.
                using (Stream stream = linker.Allocate(symbolName, SectionKind.Text, 0, nativePointerAlignment))
                {
                    // Method table and sync block
                    linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, symbolName, 0, 0, @"System.String$mtable", IntPtr.Zero);
                    stream.WriteZeroBytes(8);

                    // String length field
                    stream.Write(BitConverter.GetBytes(referencedString.Length), 0, nativePointerSize);

                    // String data
                    byte[] stringData = Encoding.Unicode.GetBytes(referencedString);
                    Debug.Assert(stringData.Length == referencedString.Length * 2, @"Byte array of string data doesn't match expected string data length");
                    stream.Write(stringData);
                }

            }

            Operand source = new SymbolOperand(BuiltInSigType.String, symbolName);
            Operand destination = context.Result;

            context.SetInstruction(IRInstruction.Move, destination, source);
        }