コード例 #1
0
ファイル: DelegateGen.cs プロジェクト: SperoSophia/il2bc
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="objectResult">
        /// </param>
        /// <param name="methodResult">
        /// </param>
        /// <param name="invokeMethod">
        /// </param>
        /// <param name="isStatic">
        /// </param>
        /// <returns>
        /// </returns>
        public static FullyDefinedReference WriteCallInvokeMethod(
            this LlvmWriter llvmWriter, FullyDefinedReference objectResult, FullyDefinedReference methodResult, IMethod invokeMethod, bool isStatic)
        {
            var writer = llvmWriter.Output;

            var method = new SynthesizedInvokeMethod(llvmWriter, objectResult, methodResult, invokeMethod, isStatic);
            var opCodeNope = OpCodePart.CreateNop;

            opCodeNope.OpCodeOperands =
                Enumerable.Range(0, invokeMethod.GetParameters().Count()).Select(p => new OpCodeInt32Part(OpCodesEmit.Ldarg, 0, 0, p + 1)).ToArray();

            foreach (var generatedOperand in opCodeNope.OpCodeOperands)
            {
                llvmWriter.ActualWrite(writer, generatedOperand);
            }

            writer.WriteLine(string.Empty);

            // bitcast object to method
            var opCodeNopeForBitCast = OpCodePart.CreateNop;
            opCodeNopeForBitCast.OpCodeOperands = new[] { OpCodePart.CreateNop };
            opCodeNopeForBitCast.OpCodeOperands[0].Result = methodResult;
            llvmWriter.UnaryOper(writer, opCodeNopeForBitCast, "bitcast", methodResult.Type, options: LlvmWriter.OperandOptions.GenerateResult);
            writer.Write(" to ");
            llvmWriter.WriteMethodPointerType(writer, method);
            writer.WriteLine(string.Empty);

            method.MethodResult = opCodeNopeForBitCast.Result;

            // actual call
            llvmWriter.WriteCall(opCodeNope, method, false, !isStatic, false, objectResult, llvmWriter.tryScopes.Count > 0 ? llvmWriter.tryScopes.Peek() : null);
            writer.WriteLine(string.Empty);

            return opCodeNope.Result;
        }
コード例 #2
0
ファイル: DelegateGen.cs プロジェクト: SperoSophia/il2bc
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="method">
        /// </param>
        private static void WriteDelegateConstructor(this LlvmWriter llvmWriter, IMethod method)
        {
            var writer = llvmWriter.Output;

            writer.WriteLine(" {");
            writer.Indent++;

            var opCode = OpCodePart.CreateNop;

            // create this variable
            llvmWriter.WriteArgumentCopyDeclaration(null, 0, method.DeclaringType, true);
            for (var i = 1; i <= llvmWriter.GetArgCount() + 1; i++)
            {
                llvmWriter.WriteArgumentCopyDeclaration(llvmWriter.GetArgName(i), i, llvmWriter.GetArgType(i));
            }

            // load 'this' variable
            llvmWriter.WriteLlvmLoad(opCode, method.DeclaringType, new FullyDefinedReference(llvmWriter.GetThisName(), method.DeclaringType));
            writer.WriteLine(string.Empty);

            var thisResult = opCode.Result;

            var delegateType = llvmWriter.ResolveType("System.Delegate");

            // write access to a field 1
            var _targetFieldIndex = llvmWriter.GetFieldIndex(delegateType, "_target");
            llvmWriter.WriteFieldAccess(writer, opCode, method.DeclaringType, delegateType, _targetFieldIndex, thisResult);
            writer.WriteLine(string.Empty);

            // load value 1
            opCode.OpCodeOperands = new[] { new OpCodePart(OpCodesEmit.Ldarg_1, 0, 0) };
            llvmWriter.ActualWrite(writer, opCode.OpCodeOperands[0]);
            writer.WriteLine(string.Empty);

            // save value 1
            llvmWriter.SaveToField(opCode, opCode.Result.Type, 0);
            writer.WriteLine(string.Empty);

            // write access to a field 2
            var _methodPtrFieldIndex = llvmWriter.GetFieldIndex(delegateType, "_methodPtr");
            llvmWriter.WriteFieldAccess(writer, opCode, method.DeclaringType, delegateType, _methodPtrFieldIndex, thisResult);
            writer.WriteLine(string.Empty);

            // load value 2
            opCode.OpCodeOperands = new[] { new OpCodePart(OpCodesEmit.Ldarg_2, 0, 0) };
            llvmWriter.ActualWrite(writer, opCode.OpCodeOperands[0]);
            writer.WriteLine(string.Empty);

            // save value 2
            llvmWriter.SaveToField(opCode, opCode.Result.Type, 0);
            writer.WriteLine(string.Empty);

            writer.WriteLine("ret void");

            writer.Indent--;
            writer.WriteLine("}");
        }
コード例 #3
0
        /// <summary>
        /// </summary>
        /// <param name="llvmWriter">
        /// </param>
        /// <param name="opCode">
        /// </param>
        /// <param name="declaringType">
        /// </param>
        /// <param name="newObjectResult">
        /// </param>
        /// <param name="callInit">
        /// </param>
        public static void WriteBoxObject(
            this LlvmWriter llvmWriter, OpCodePart opCode, IType declaringType, FullyDefinedReference newObjectResult = null, bool callInit = false)
        {
            var writer = llvmWriter.Output;

            var valueLoadResult = opCode.Result;

            var isStruct = declaringType.ToNormal().IsStructureType();

            opCode.Result = null;

            writer.WriteLine("; Boxing");

            writer.WriteLine(string.Empty);
            llvmWriter.CheckIfExternalDeclarationIsRequired(declaringType);

            // call new if null
            if (newObjectResult == null)
            {
                declaringType.WriteCallNewObjectMethod(llvmWriter, opCode);
                newObjectResult = opCode.Result;
            }
            else
            {
                opCode.Result = newObjectResult;
            }

            writer.WriteLine(string.Empty);
            writer.WriteLine("; Copy data");

            if (!isStruct)
            {
                // write access to a field
                if (!llvmWriter.WriteFieldAccess(
                        writer, 
                        opCode, 
                        declaringType.ToClass(), 
                        declaringType.ToClass(), 
                        0, 
                        opCode.Result))
                {
                    writer.WriteLine("; No data");
                    return;
                }

                writer.WriteLine(string.Empty);
            }

            var fieldType = declaringType.ToNormal();

            opCode.OpCodeOperands = new[] { new OpCodePart(OpCodesEmit.Ldarg_0, 0, 0) };
            opCode.OpCodeOperands[0].Result = valueLoadResult;
            if (valueLoadResult == null)
            {
                llvmWriter.ActualWrite(writer, opCode.OpCodeOperands[0]);
            }

            llvmWriter.SaveToField(opCode, fieldType, 0);

            writer.WriteLine(string.Empty);
            writer.WriteLine("; End of Copy data");

            if (callInit)
            {
                opCode.Result = newObjectResult;
                declaringType.WriteCallInitObjectMethod(llvmWriter, opCode);
                writer.WriteLine(string.Empty);
            }

            opCode.Result = newObjectResult.ToClassType();
        }