mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-13 07:23:39 +00:00
compiler: implement make([]T, ...)
This commit is contained in:
+42
@@ -2087,6 +2087,48 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||
llvmValueSize := llvm.ConstInt(llvm.Int8Type(), valueSize, false)
|
||||
hashmap := c.builder.CreateCall(hashmapMake, []llvm.Value{llvmKeySize, llvmValueSize}, "")
|
||||
return hashmap, nil
|
||||
case *ssa.MakeSlice:
|
||||
sliceLen, err := c.parseExpr(frame, expr.Len)
|
||||
if err != nil {
|
||||
return llvm.Value{}, nil
|
||||
}
|
||||
sliceCap, err := c.parseExpr(frame, expr.Cap)
|
||||
if err != nil {
|
||||
return llvm.Value{}, nil
|
||||
}
|
||||
sliceType := expr.Type().Underlying().(*types.Slice)
|
||||
llvmElemType, err := c.getLLVMType(sliceType.Elem())
|
||||
if err != nil {
|
||||
return llvm.Value{}, nil
|
||||
}
|
||||
elemSize := c.targetData.TypeAllocSize(llvmElemType)
|
||||
|
||||
// Bounds checking.
|
||||
if !frame.fn.nobounds {
|
||||
sliceBoundsCheck := c.mod.NamedFunction("runtime.sliceBoundsCheckMake")
|
||||
c.builder.CreateCall(sliceBoundsCheck, []llvm.Value{sliceLen, sliceCap}, "")
|
||||
}
|
||||
|
||||
// Allocate the backing array.
|
||||
// TODO: escape analysis
|
||||
elemSizeValue := llvm.ConstInt(c.uintptrType, elemSize, false)
|
||||
sliceCapCast, err := c.parseConvert(expr.Cap.Type(), types.Typ[types.Uintptr], sliceCap)
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
sliceSize := c.builder.CreateBinOp(llvm.Mul, elemSizeValue, sliceCapCast, "makeslice.cap")
|
||||
slicePtr := c.builder.CreateCall(c.allocFunc, []llvm.Value{sliceSize}, "makeslice.buf")
|
||||
|
||||
// Create the slice.
|
||||
slice := llvm.ConstStruct([]llvm.Value{
|
||||
llvm.Undef(slicePtr.Type()),
|
||||
llvm.Undef(c.lenType),
|
||||
llvm.Undef(c.lenType),
|
||||
}, false)
|
||||
slice = c.builder.CreateInsertValue(slice, slicePtr, 0, "")
|
||||
slice = c.builder.CreateInsertValue(slice, sliceLen, 1, "")
|
||||
slice = c.builder.CreateInsertValue(slice, sliceCap, 2, "")
|
||||
return slice, nil
|
||||
case *ssa.Phi:
|
||||
t, err := c.getLLVMType(expr.Type())
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user