示例#1
0
        private ForStatementUpNode Visit(ForStatementUpNode node)
        {
            Visit(node.expr1);
            builder.BuildStore(GetProperty(node.expr1).addr, LookupSymbolOrAlloc(node.Identifier));
            var condBB = func.AppendBasicBlock($"cond_{++count}");
            var bodyBB = func.AppendBasicBlock($"body_{++count}");
            var contBB = func.AppendBasicBlock($"cont_{++count}");

            builder.BuildBr(condBB);
            builder.PositionAtEnd(condBB);
            Visit(node.expr2);
            var t = builder.BuildLoad(LookupSymbolOrAlloc(node.Identifier));
            var b = builder.BuildICmp(LLVMIntPredicate.LLVMIntSLT, t, GetProperty(node.expr2).addr);

            builder.BuildCondBr(b, bodyBB, contBB);
            builder.PositionAtEnd(bodyBB);
            Visit(node.StatementNode);
            t = builder.BuildLoad(LookupSymbolOrAlloc(node.Identifier));
            var r = builder.BuildAdd(t, LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 1));

            builder.BuildStore(r, LookupSymbolOrAlloc(node.Identifier));
            builder.BuildBr(condBB);
            builder.PositionAtEnd(contBB);
            return(node);
        }
示例#2
0
        private LLVMValueRef OutputCodeForDictionaryLookup(LLVMBuilderRef builder, NodeFactory factory,
                                                           ReadyToRunGenericHelperNode node, GenericLookupResult lookup, LLVMValueRef ctx, string gepName)
        {
            // Find the generic dictionary slot
            int dictionarySlot = factory.GenericDictionaryLayout(node.DictionaryOwner).GetSlotForEntry(lookup);
            int offset         = dictionarySlot * factory.Target.PointerSize;

            // Load the generic dictionary cell
            LLVMValueRef retGep  = builder.BuildGEP(ctx, new[] { LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, (ulong)offset, false) }, "retGep");
            LLVMValueRef castGep = builder.BuildBitCast(retGep, LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), "ptrPtr");
            LLVMValueRef retRef  = builder.BuildLoad(castGep, gepName);

            switch (lookup.LookupResultReferenceType(factory))
            {
            case GenericLookupResultReferenceType.Indirect:
                var ptrPtr = builder.BuildBitCast(retRef, LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), "ptrPtr");
                retRef = builder.BuildLoad(ptrPtr, "indLoad");
                break;

            case GenericLookupResultReferenceType.ConditionalIndirect:
                throw new NotImplementedException();

            default:
                break;
            }

            return(retRef);
        }
示例#3
0
        public void OutputCodeForDelegateCtorInit(LLVMBuilderRef builder, LLVMValueRef helperFunc,
                                                  MethodDesc constructor,
                                                  LLVMValueRef fatFunction)
        {
            StackEntry[] argValues   = new StackEntry [constructor.Signature.Length + 1]; // for delegate this
            var          shadowStack = helperFunc.GetParam(0);

            argValues[0] = new LoadExpressionEntry(StackValueKind.ObjRef, "this", shadowStack, GetWellKnownType(WellKnownType.Object));
            for (var i = 0; i < constructor.Signature.Length; i++)
            {
                if (i == 1)
                {
                    argValues[i + 1] = new ExpressionEntry(StackValueKind.Int32, "arg" + (i + 1),
                                                           builder.BuildIntToPtr(fatFunction, LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "toPtr"),
                                                           GetWellKnownType(WellKnownType.IntPtr));
                }
                else
                {
                    var argRef = LoadVarAddress(i + 1, LocalVarKind.Argument, out TypeDesc type);
                    var ptrPtr = builder.BuildPointerCast(argRef,
                                                          LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), "ptrPtr");
                    var loadArg = builder.BuildLoad(ptrPtr, "arg" + (i + 1));
                    argValues[i + 1] = new ExpressionEntry(GetStackValueKind(constructor.Signature[i]), "arg" + i + 1, loadArg,
                                                           constructor.Signature[i]);
                }
            }
            HandleCall(constructor, constructor.Signature, constructor, argValues, null);
        }
示例#4
0
        private void GetCodeForReadyToRunGenericHelper(WebAssemblyCodegenCompilation compilation, ReadyToRunGenericHelperNode node, NodeFactory factory)
        {
            LLVMBuilderRef builder      = compilation.Module.Context.CreateBuilder();
            var            args         = new List <LLVMTypeRef>();
            MethodDesc     delegateCtor = null;

            if (node.Id == ReadyToRunHelperId.DelegateCtor)
            {
                DelegateCreationInfo target = (DelegateCreationInfo)node.Target;
                delegateCtor = target.Constructor.Method;
                bool isStatic = delegateCtor.Signature.IsStatic;
                int  argCount = delegateCtor.Signature.Length;
                if (!isStatic)
                {
                    argCount++;
                }
                for (int i = 0; i < argCount; i++)
                {
                    TypeDesc argType;
                    if (i == 0 && !isStatic)
                    {
                        argType = delegateCtor.OwningType;
                    }
                    else
                    {
                        argType = delegateCtor.Signature[i - (isStatic ? 0 : 1)];
                    }
                    args.Add(ILImporter.GetLLVMTypeForTypeDesc(argType));
                }
            }

            LLVMValueRef helperFunc = Module.GetNamedFunction(node.GetMangledName(factory.NameMangler));

            if (helperFunc.Handle == IntPtr.Zero)
            {
                throw new Exception("if the function is requested here, it should have been created earlier");
            }
            var helperBlock = helperFunc.AppendBasicBlock("genericHelper");

            builder.PositionAtEnd(helperBlock);
            var          importer = new ILImporter(builder, compilation, Module, helperFunc, delegateCtor);
            LLVMValueRef ctx;
            string       gepName;

            if (node is ReadyToRunGenericLookupFromTypeNode)
            {
                // Locate the VTable slot that points to the dictionary
                int vtableSlot = VirtualMethodSlotHelper.GetGenericDictionarySlot(factory, (TypeDesc)node.DictionaryOwner);

                int pointerSize = factory.Target.PointerSize;
                // Load the dictionary pointer from the VTable
                int slotOffset    = EETypeNode.GetVTableOffset(pointerSize) + (vtableSlot * pointerSize);
                var slotGep       = builder.BuildGEP(helperFunc.GetParam(1), new[] { LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, (ulong)slotOffset, false) }, "slotGep");
                var slotGepPtrPtr = builder.BuildPointerCast(slotGep,
                                                             LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), "slotGepPtrPtr");
                ctx     = builder.BuildLoad(slotGepPtrPtr, "dictGep");
                gepName = "typeNodeGep";
            }
            else
            {
                ctx     = helperFunc.GetParam(1);
                gepName = "paramGep";
            }

            LLVMValueRef resVar = OutputCodeForDictionaryLookup(builder, factory, node, node.LookupSignature, ctx, gepName);

            switch (node.Id)
            {
            case ReadyToRunHelperId.GetNonGCStaticBase:
            {
                MetadataType target = (MetadataType)node.Target;

                if (compilation.TypeSystemContext.HasLazyStaticConstructor(target))
                {
                    importer.OutputCodeForTriggerCctor(target, resVar);
                }
            }
            break;

            case ReadyToRunHelperId.GetGCStaticBase:
            {
                MetadataType target = (MetadataType)node.Target;

                var ptrPtrPtr = builder.BuildBitCast(resVar, LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), 0), 0), "ptrPtrPtr");

                resVar = builder.BuildLoad(builder.BuildLoad(ptrPtrPtr, "ind1"), "ind2");

                if (compilation.TypeSystemContext.HasLazyStaticConstructor(target))
                {
                    GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(target);
                    var nonGcStaticsBase = OutputCodeForDictionaryLookup(builder, factory, node, nonGcRegionLookup, ctx, "lazyGep");
                    importer.OutputCodeForTriggerCctor(target, nonGcStaticsBase);
                }
            }
            break;

            case ReadyToRunHelperId.GetThreadStaticBase:
            {
                MetadataType target = (MetadataType)node.Target;

                if (compilation.TypeSystemContext.HasLazyStaticConstructor(target))
                {
                    GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(target);
                    var threadStaticBase = OutputCodeForDictionaryLookup(builder, factory, node, nonGcRegionLookup, ctx, "tsGep");
                    importer.OutputCodeForTriggerCctor(target, threadStaticBase);
                }
                resVar = importer.OutputCodeForGetThreadStaticBaseForType(resVar).ValueAsType(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), builder);
            }
            break;

            case ReadyToRunHelperId.DelegateCtor:
            {
                DelegateCreationInfo target      = (DelegateCreationInfo)node.Target;
                MethodDesc           constructor = target.Constructor.Method;
                var fatPtr = ILImporter.MakeFatPointer(builder, resVar, compilation);
                importer.OutputCodeForDelegateCtorInit(builder, helperFunc, constructor, fatPtr);
            }
            break;

            // These are all simple: just get the thing from the dictionary and we're done
            case ReadyToRunHelperId.TypeHandle:
            case ReadyToRunHelperId.MethodHandle:
            case ReadyToRunHelperId.FieldHandle:
            case ReadyToRunHelperId.MethodDictionary:
            case ReadyToRunHelperId.MethodEntry:
            case ReadyToRunHelperId.VirtualDispatchCell:
            case ReadyToRunHelperId.DefaultConstructor:
                break;

            default:
                throw new NotImplementedException();
            }

            if (node.Id != ReadyToRunHelperId.DelegateCtor)
            {
                builder.BuildRet(resVar);
            }
            else
            {
                builder.BuildRetVoid();
            }
        }