diff --git a/compiler/compiler.go b/compiler/compiler.go index 6c0c98b2..86b20306 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -270,6 +270,10 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, // Predeclare the runtime.alloc function, which is used by the wordpack // functionality. c.getFunction(c.program.ImportedPackage("runtime").Members["alloc"].(*ssa.Function)) + if c.NeedsStackObjects { + // Predeclare trackPointer, which is used everywhere we use runtime.alloc. + c.getFunction(c.program.ImportedPackage("runtime").Members["trackPointer"].(*ssa.Function)) + } // Compile all functions, methods, and global variables in this package. irbuilder := c.ctx.NewBuilder() diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go index 65a1c626..ef22faca 100644 --- a/compiler/compiler_test.go +++ b/compiler/compiler_test.go @@ -109,6 +109,7 @@ func TestCompiler(t *testing.T) { FuncImplementation: config.FuncImplementation(), AutomaticStackSize: config.AutomaticStackSize(), DefaultStackSize: config.Target.DefaultStackSize, + NeedsStackObjects: config.NeedsStackObjects(), } machine, err := NewTargetMachine(compilerConfig) if err != nil { diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll index 69b72f27..569b2f7f 100644 --- a/compiler/testdata/basic.ll +++ b/compiler/testdata/basic.ll @@ -8,6 +8,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll index fa80db5d..86c6417d 100644 --- a/compiler/testdata/channel.ll +++ b/compiler/testdata/channel.ll @@ -13,6 +13,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -63,7 +65,10 @@ declare i1 @runtime.chanRecv(%runtime.channel* dereferenceable_or_null(32), i8*, ; Function Attrs: nounwind define hidden void @main.chanZeroSend(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + %complit = alloca {}, align 8 %chan.blockedList = alloca %runtime.channelBlockedList, align 8 + %0 = bitcast {}* %complit to i8* + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8* call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) call void @runtime.chanSend(%runtime.channel* %ch, i8* null, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef, i8* null) #0 diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll index e96f8cd7..15bf39d7 100644 --- a/compiler/testdata/float.ll +++ b/compiler/testdata/float.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/func-coroutines.ll b/compiler/testdata/func-coroutines.ll index b88ce514..d9c5c4d4 100644 --- a/compiler/testdata/func-coroutines.ll +++ b/compiler/testdata/func-coroutines.ll @@ -10,6 +10,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll index 7443c5d4..79f0bce5 100644 --- a/compiler/testdata/gc.ll +++ b/compiler/testdata/gc.ll @@ -28,6 +28,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -38,12 +40,16 @@ entry: define hidden void @main.newScalar(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %new = call i8* @runtime.alloc(i32 1, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 store i8* %new, i8** @main.scalar1, align 4 %new1 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new1, i8* undef, i8* null) #0 store i8* %new1, i8** bitcast (i32** @main.scalar2 to i8**), align 4 %new2 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new2, i8* undef, i8* null) #0 store i8* %new2, i8** bitcast (i64** @main.scalar3 to i8**), align 4 %new3 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new3, i8* undef, i8* null) #0 store i8* %new3, i8** bitcast (float** @main.scalar4 to i8**), align 4 ret void } @@ -52,10 +58,13 @@ entry: define hidden void @main.newArray(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %new = call i8* @runtime.alloc(i32 3, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 store i8* %new, i8** bitcast ([3 x i8]** @main.array1 to i8**), align 4 %new1 = call i8* @runtime.alloc(i32 71, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new1, i8* undef, i8* null) #0 store i8* %new1, i8** bitcast ([71 x i8]** @main.array2 to i8**), align 4 %new2 = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 67 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new2, i8* undef, i8* null) #0 store i8* %new2, i8** bitcast ([3 x i8*]** @main.array3 to i8**), align 4 ret void } @@ -64,12 +73,16 @@ entry: define hidden void @main.newStruct(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %new = call i8* @runtime.alloc(i32 0, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 store i8* %new, i8** bitcast ({}** @main.struct1 to i8**), align 4 %new1 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new1, i8* undef, i8* null) #0 store i8* %new1, i8** bitcast ({ i32, i32 }** @main.struct2 to i8**), align 4 %new2 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-2000000000000001" to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new2, i8* undef, i8* null) #0 store i8* %new2, i8** bitcast ({ i8*, [60 x i32], i8* }** @main.struct3 to i8**), align 4 %new3 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-0001" to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new3, i8* undef, i8* null) #0 store i8* %new3, i8** bitcast ({ i8*, [61 x i32] }** @main.struct4 to i8**), align 4 ret void } @@ -79,6 +92,7 @@ define hidden { i8*, void ()* }* @main.newFuncValue(i8* %context, i8* %parentHan entry: %new = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 197 to i8*), i8* undef, i8* null) #0 %0 = bitcast i8* %new to { i8*, void ()* }* + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 ret { i8*, void ()* }* %0 } @@ -86,14 +100,17 @@ entry: define hidden void @main.makeSlice(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %makeslice = call i8* @runtime.alloc(i32 5, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef, i8* null) #0 store i8* %makeslice, i8** getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 0), align 8 store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 1), align 4 store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 2), align 8 %makeslice1 = call i8* @runtime.alloc(i32 20, i8* nonnull inttoptr (i32 67 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice1, i8* undef, i8* null) #0 store i8* %makeslice1, i8** bitcast ({ i32**, i32, i32 }* @main.slice2 to i8**), align 8 store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 1), align 4 store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 2), align 8 %makeslice3 = call i8* @runtime.alloc(i32 60, i8* nonnull inttoptr (i32 71 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice3, i8* undef, i8* null) #0 store i8* %makeslice3, i8** bitcast ({ { i8*, i32, i32 }*, i32, i32 }* @main.slice3 to i8**), align 8 store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 1), align 4 store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 2), align 8 @@ -104,12 +121,14 @@ entry: define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %.repack = bitcast i8* %0 to double* store double %v.r, double* %.repack, align 8 %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 %1 = bitcast i8* %.repack1 to double* store double %v.i, double* %1, align 8 %2 = insertvalue %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:complex128" to i32), i8* undef }, i8* %0, 1 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 ret %runtime._interface %2 } diff --git a/compiler/testdata/go1.17.ll b/compiler/testdata/go1.17.ll index 1499547f..5b50cb50 100644 --- a/compiler/testdata/go1.17.ll +++ b/compiler/testdata/go1.17.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -15,6 +17,7 @@ entry: define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = getelementptr i8, i8* %p, i32 %len + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 ret i8* %0 } @@ -23,6 +26,7 @@ define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context, i8* %parentHandle) entry: %0 = trunc i64 %len to i32 %1 = getelementptr i8, i8* %p, i32 %0 + call void @runtime.trackPointer(i8* %1, i8* undef, i8* null) #0 ret i8* %1 } @@ -47,6 +51,7 @@ declare void @runtime.sliceToArrayPointerPanic(i8*, i8*) define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef, i8* null) #0 br i1 false, label %slicetoarray.throw, label %slicetoarray.next slicetoarray.throw: ; preds = %entry @@ -75,6 +80,8 @@ unsafe.Slice.next: ; preds = %entry %5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 %6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1 %7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2 + %8 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %8, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %7 } @@ -97,6 +104,7 @@ unsafe.Slice.next: ; preds = %entry %4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0 %5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1 %6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2 + call void @runtime.trackPointer(i8* %ptr, i8* undef, i8* null) #0 ret { i8*, i32, i32 } %6 } @@ -119,6 +127,8 @@ unsafe.Slice.next: ; preds = %entry %6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 %7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 %8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 + %9 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %9, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %8 } @@ -141,6 +151,8 @@ unsafe.Slice.next: ; preds = %entry %6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 %7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 %8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 + %9 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %9, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %8 } diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll index aa01d0f4..76473cda 100644 --- a/compiler/testdata/goroutine-wasm-asyncify.ll +++ b/compiler/testdata/goroutine-wasm-asyncify.ll @@ -15,6 +15,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -70,8 +72,12 @@ define hidden void @main.closureFunctionGoroutine(i8* %context, i8* %parentHandl entry: %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 %0 = bitcast i8* %n to i32* + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 store i32 3, i32* %0, align 4 + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* bitcast (void (i32, i8*, i8*)* @"main.closureFunctionGoroutine$1" to i8*), i8* undef, i8* null) #0 %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %1, i8* undef, i8* null) #0 %2 = bitcast i8* %1 to i32* store i32 5, i32* %2, align 4 %3 = getelementptr inbounds i8, i8* %1, i32 4 @@ -110,6 +116,7 @@ declare void @runtime.printint32(i32, i8*, i8*) define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %1 = bitcast i8* %0 to i32* store i32 5, i32* %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 @@ -166,6 +173,7 @@ declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %1 = bitcast i8* %0 to i8** store i8* %itf.value, i8** %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 diff --git a/compiler/testdata/goroutine-wasm-coroutines.ll b/compiler/testdata/goroutine-wasm-coroutines.ll index fe7b89b5..42a7d6e1 100644 --- a/compiler/testdata/goroutine-wasm-coroutines.ll +++ b/compiler/testdata/goroutine-wasm-coroutines.ll @@ -19,6 +19,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -54,8 +56,11 @@ define hidden void @main.closureFunctionGoroutine(i8* %context, i8* %parentHandl entry: %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 %0 = bitcast i8* %n to i32* + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 store i32 3, i32* %0, align 4 + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %1, i8* undef, i8* null) #0 %2 = bitcast i8* %1 to i32* store i32 5, i32* %2, align 4 %3 = getelementptr inbounds i8, i8* %1, i32 4 @@ -82,6 +87,7 @@ define hidden void @main.funcGoroutine(i8* %fn.context, i32 %fn.funcptr, i8* %co entry: %0 = call i32 @runtime.getFuncPtr(i8* %fn.context, i32 %fn.funcptr, i8* nonnull @"reflect/types.funcid:func:{basic:int}{}", i8* undef, i8* null) #0 %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %1, i8* undef, i8* null) #0 %2 = bitcast i8* %1 to i32* store i32 5, i32* %2, align 4 %3 = getelementptr inbounds i8, i8* %1, i32 4 @@ -121,6 +127,7 @@ declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %1 = bitcast i8* %0 to i8** store i8* %itf.value, i8** %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll index c27142ec..c9ff0a90 100644 --- a/compiler/testdata/interface.ll +++ b/compiler/testdata/interface.ll @@ -24,6 +24,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -33,18 +35,21 @@ entry: ; Function Attrs: nounwind define hidden %runtime._interface @main.simpleType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:int" to i32), i8* null } } ; Function Attrs: nounwind define hidden %runtime._interface @main.pointerType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:basic:int" to i32), i8* null } } ; Function Attrs: nounwind define hidden %runtime._interface @main.interfaceType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:named:error" to i32), i8* null } } @@ -53,6 +58,7 @@ declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #1 ; Function Attrs: nounwind define hidden %runtime._interface @main.anonymousInterfaceType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), i8* null } } @@ -112,6 +118,8 @@ declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{b define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, i8* %itf.value, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8* %itf.value, i32 %itf.typecode, i8* undef, i8* undef) #0 + %1 = extractvalue %runtime._string %0, 0 + call void @runtime.trackPointer(i8* %1, i8* undef, i8* null) #0 ret %runtime._string %0 } diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll index ce20dfd0..e24e61c3 100644 --- a/compiler/testdata/intrinsics-wasm.ll +++ b/compiler/testdata/intrinsics-wasm.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll index 7020c0fa..e236db83 100644 --- a/compiler/testdata/pointer.ll +++ b/compiler/testdata/pointer.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -21,6 +23,7 @@ entry: define hidden i32* @main.pointerCastFromUnsafe(i8* %x, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = bitcast i8* %x to i32* + call void @runtime.trackPointer(i8* %x, i8* undef, i8* null) #0 ret i32* %0 } @@ -28,34 +31,48 @@ entry: define hidden i8* @main.pointerCastToUnsafe(i32* dereferenceable_or_null(4) %x, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = bitcast i32* %x to i8* + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 ret i8* %0 } ; Function Attrs: nounwind define hidden i8* @main.pointerCastToUnsafeNoop(i8* dereferenceable_or_null(1) %x, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* %x, i8* undef, i8* null) #0 ret i8* %x } ; Function Attrs: nounwind define hidden i8* @main.pointerUnsafeGEPFixedOffset(i8* dereferenceable_or_null(1) %ptr, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* %ptr, i8* undef, i8* null) #0 %0 = getelementptr inbounds i8, i8* %ptr, i32 10 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 ret i8* %0 } ; Function Attrs: nounwind define hidden i8* @main.pointerUnsafeGEPByteOffset(i8* dereferenceable_or_null(1) %ptr, i32 %offset, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* %ptr, i8* undef, i8* null) #0 %0 = getelementptr inbounds i8, i8* %ptr, i32 %offset + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 ret i8* %0 } ; Function Attrs: nounwind define hidden i32* @main.pointerUnsafeGEPIntOffset(i32* dereferenceable_or_null(4) %ptr, i32 %offset, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %0 = getelementptr i32, i32* %ptr, i32 %offset - ret i32* %0 + %0 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 + %1 = getelementptr i32, i32* %ptr, i32 %offset + %2 = bitcast i32* %1 to i8* + call void @runtime.trackPointer(i8* %2, i8* undef, i8* null) #0 + %3 = bitcast i32* %1 to i8* + call void @runtime.trackPointer(i8* %3, i8* undef, i8* null) #0 + ret i32* %1 } attributes #0 = { nounwind } diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index 943b574d..ee189c3f 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -12,6 +12,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll index 0cca8970..98d2b128 100644 --- a/compiler/testdata/slice.ll +++ b/compiler/testdata/slice.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -45,6 +47,7 @@ declare void @runtime.lookupPanic(i8*, i8*) define hidden { i32*, i32, i32 } @main.sliceAppendValues(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %varargs = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %varargs, i8* undef, i8* null) #0 %0 = bitcast i8* %varargs to i32* store i32 1, i32* %0, align 4 %1 = getelementptr inbounds i8, i8* %varargs, i32 4 @@ -62,6 +65,7 @@ entry: %5 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0 %6 = insertvalue { i32*, i32, i32 } %5, i32 %append.newLen, 1 %7 = insertvalue { i32*, i32, i32 } %6, i32 %append.newCap, 2 + call void @runtime.trackPointer(i8* %append.newPtr, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %7 } @@ -80,6 +84,7 @@ entry: %0 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0 %1 = insertvalue { i32*, i32, i32 } %0, i32 %append.newLen, 1 %2 = insertvalue { i32*, i32, i32 } %1, i32 %append.newCap, 2 + call void @runtime.trackPointer(i8* %append.newPtr, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %2 } @@ -109,6 +114,7 @@ slice.next: ; preds = %entry %0 = insertvalue { i8*, i32, i32 } undef, i8* %makeslice.buf, 0 %1 = insertvalue { i8*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { i8*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { i8*, i32, i32 } %2 } @@ -131,6 +137,7 @@ slice.next: ; preds = %entry %0 = insertvalue { i16*, i32, i32 } undef, i16* %makeslice.array, 0 %1 = insertvalue { i16*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { i16*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { i16*, i32, i32 } %2 } @@ -151,6 +158,7 @@ slice.next: ; preds = %entry %0 = insertvalue { [3 x i8]*, i32, i32 } undef, [3 x i8]* %makeslice.array, 0 %1 = insertvalue { [3 x i8]*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { [3 x i8]*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { [3 x i8]*, i32, i32 } %2 } @@ -171,6 +179,7 @@ slice.next: ; preds = %entry %0 = insertvalue { i32*, i32, i32 } undef, i32* %makeslice.array, 0 %1 = insertvalue { i32*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { i32*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %2 } diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll index 93f76059..ecbb6f0f 100644 --- a/compiler/testdata/string.ll +++ b/compiler/testdata/string.ll @@ -9,6 +9,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: