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); }
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); }
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); }
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(); } }