MCPcopy Index your code
hub / github.com/tinygo-org/tinygo / zeroUndefBytes

Method zeroUndefBytes

compiler/map.go:274–338  ·  view source on GitHub ↗
(llvmType llvm.Type, ptr llvm.Value)

Source from the content-addressed store, hash-verified

272}
273
274func (b *builder) zeroUndefBytes(llvmType llvm.Type, ptr llvm.Value) error {
275 // We know that hashmapIsBinaryKey is true, so we only have to handle those types that can show up there.
276 // To zero all undefined bytes, we iterate over all the fields in the type. For each element, compute the
277 // offset of that element. If it's Basic type, there are no internal padding bytes. For compound types, we recurse to ensure
278 // we handle nested types. Next, we determine if there are any padding bytes before the next
279 // element and zero those as well.
280
281 zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
282
283 switch llvmType.TypeKind() {
284 case llvm.IntegerTypeKind:
285 // no padding bytes
286 return nil
287 case llvm.PointerTypeKind:
288 // mo padding bytes
289 return nil
290 case llvm.ArrayTypeKind:
291 llvmArrayType := llvmType
292 llvmElemType := llvmType.ElementType()
293
294 for i := 0; i < llvmArrayType.ArrayLength(); i++ {
295 idx := llvm.ConstInt(b.uintptrType, uint64(i), false)
296 elemPtr := b.CreateInBoundsGEP(llvmArrayType, ptr, []llvm.Value{zero, idx}, "")
297
298 // zero any padding bytes in this element
299 b.zeroUndefBytes(llvmElemType, elemPtr)
300 }
301
302 case llvm.StructTypeKind:
303 llvmStructType := llvmType
304 numFields := llvmStructType.StructElementTypesCount()
305 llvmElementTypes := llvmStructType.StructElementTypes()
306
307 for i := 0; i < numFields; i++ {
308 idx := llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)
309 elemPtr := b.CreateInBoundsGEP(llvmStructType, ptr, []llvm.Value{zero, idx}, "")
310
311 // zero any padding bytes in this field
312 llvmElemType := llvmElementTypes[i]
313 b.zeroUndefBytes(llvmElemType, elemPtr)
314
315 // zero any padding bytes before the next field, if any
316 offset := b.targetData.ElementOffset(llvmStructType, i)
317 storeSize := b.targetData.TypeStoreSize(llvmElemType)
318 fieldEndOffset := offset + storeSize
319
320 var nextOffset uint64
321 if i < numFields-1 {
322 nextOffset = b.targetData.ElementOffset(llvmStructType, i+1)
323 } else {
324 // Last field? Next offset is the total size of the allocate struct.
325 nextOffset = b.targetData.TypeAllocSize(llvmStructType)
326 }
327
328 if fieldEndOffset != nextOffset {
329 n := llvm.ConstInt(b.uintptrType, nextOffset-fieldEndOffset, false)
330 llvmStoreSize := llvm.ConstInt(b.uintptrType, storeSize, false)
331 paddingStart := b.CreateInBoundsGEP(b.ctx.Int8Type(), elemPtr, []llvm.Value{llvmStoreSize}, "")

Callers 3

createMapLookupMethod · 0.95
createMapUpdateMethod · 0.95
createMapDeleteMethod · 0.95

Calls 1

createRuntimeCallMethod · 0.95

Tested by

no test coverage detected