mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 14:48:40 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89ffb47a0c | |||
| 2f7952ff29 |
@@ -747,6 +747,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
}
|
||||
ldflags = append(ldflags, "-mllvm", "-mcpu="+config.CPU())
|
||||
ldflags = append(ldflags, "-mllvm", "-mattr="+config.Features()) // needed for MIPS softfloat
|
||||
ldflags = append(ldflags, "-mllvm", "-wasm-enable-eh")
|
||||
if config.GOOS() == "windows" {
|
||||
// Options for the MinGW wrapper for the lld COFF linker.
|
||||
ldflags = append(ldflags,
|
||||
|
||||
+23
-8
@@ -70,21 +70,25 @@ func (b *builder) createRuntimeInvoke(fnName string, args []llvm.Value, name str
|
||||
// createCall creates a call to the given function with the arguments possibly
|
||||
// expanded.
|
||||
func (b *builder) createCall(fnType llvm.Type, fn llvm.Value, args []llvm.Value, name string) llvm.Value {
|
||||
expanded := make([]llvm.Value, 0, len(args))
|
||||
for _, arg := range args {
|
||||
fragments := b.expandFormalParam(arg)
|
||||
expanded = append(expanded, fragments...)
|
||||
}
|
||||
return b.CreateCall(fnType, fn, expanded, name)
|
||||
return b.CreateCall(fnType, fn, b.expandFormalParams(args), name)
|
||||
}
|
||||
|
||||
// createInvoke is like createCall but continues execution at the landing pad if
|
||||
// the call resulted in a panic.
|
||||
func (b *builder) createInvoke(fnType llvm.Type, fn llvm.Value, args []llvm.Value, name string) llvm.Value {
|
||||
if b.hasDeferFrame() {
|
||||
switch b.deferFrameType() {
|
||||
case recoverInlineAsm:
|
||||
b.createInvokeCheckpoint()
|
||||
return b.createCall(fnType, fn, args, name)
|
||||
case recoverWasmEH:
|
||||
continueBB := b.insertBasicBlock("invoke.cont")
|
||||
call := b.CreateInvoke(fnType, fn, b.expandFormalParams(args), continueBB, b.landingpad, name)
|
||||
b.SetInsertPointAtEnd(continueBB)
|
||||
b.blockExits[b.currentBlock] = continueBB
|
||||
return call
|
||||
default:
|
||||
return b.createCall(fnType, fn, args, name)
|
||||
}
|
||||
return b.createCall(fnType, fn, args, name)
|
||||
}
|
||||
|
||||
// Expand an argument type to a list that can be used in a function call
|
||||
@@ -123,6 +127,17 @@ func (b *builder) expandFormalParamOffsets(t llvm.Type) []uint64 {
|
||||
}
|
||||
}
|
||||
|
||||
// expandFormalParams expands every param in the params slice like
|
||||
// expandFormalParam.
|
||||
func (b *builder) expandFormalParams(params []llvm.Value) []llvm.Value {
|
||||
expanded := make([]llvm.Value, 0, len(params))
|
||||
for _, arg := range params {
|
||||
fragments := b.expandFormalParam(arg)
|
||||
expanded = append(expanded, fragments...)
|
||||
}
|
||||
return expanded
|
||||
}
|
||||
|
||||
// expandFormalParam splits a formal param value into pieces, so it can be
|
||||
// passed directly as part of a function call. For example, it splits up small
|
||||
// structs into individual fields. It is the equivalent of expandFormalParamType
|
||||
|
||||
+13
-10
@@ -355,7 +355,10 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
|
||||
}
|
||||
|
||||
func (c *compilerContext) getRuntimeType(name string) types.Type {
|
||||
return c.runtimePkg.Scope().Lookup(name).(*types.TypeName).Type()
|
||||
if typ, ok := c.runtimePkg.Scope().Lookup(name).(*types.TypeName); ok {
|
||||
return typ.Type()
|
||||
}
|
||||
panic("runtime type not found: " + name)
|
||||
}
|
||||
|
||||
// getLLVMRuntimeType obtains a named type from the runtime package and returns
|
||||
@@ -1350,7 +1353,7 @@ func (b *builder) createFunction() {
|
||||
b.CreateBr(b.afterDefersBlock[i])
|
||||
}
|
||||
|
||||
if b.hasDeferFrame() {
|
||||
if b.deferFrameType() != recoverNone {
|
||||
// Create the landing pad block, where execution continues after a
|
||||
// panic.
|
||||
b.createLandingPad()
|
||||
@@ -1487,8 +1490,11 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
||||
b.createRuntimeInvoke("_panic", []llvm.Value{value}, "")
|
||||
b.CreateUnreachable()
|
||||
case *ssa.Return:
|
||||
if b.hasDeferFrame() {
|
||||
b.createRuntimeCall("destroyDeferFrame", []llvm.Value{b.deferFrame}, "")
|
||||
switch b.deferFrameType() {
|
||||
case recoverInlineAsm:
|
||||
b.createRuntimeCall("destroyDeferFrameInlineAsm", []llvm.Value{b.deferFrame}, "")
|
||||
case recoverWasmEH:
|
||||
b.createRuntimeCall("destroyDeferFrameWasmEH", []llvm.Value{b.deferFrame}, "")
|
||||
}
|
||||
if len(instr.Results) == 0 {
|
||||
b.CreateRetVoid()
|
||||
@@ -1741,7 +1747,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
|
||||
return b.CreateExtractValue(cplx, 0, "real"), nil
|
||||
case "recover":
|
||||
useParentFrame := uint64(0)
|
||||
if b.hasDeferFrame() {
|
||||
if b.fn.Recover != nil {
|
||||
// recover() should return the panic value of the parent function,
|
||||
// not of the current function.
|
||||
useParentFrame = 1
|
||||
@@ -1851,11 +1857,8 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
||||
case strings.HasPrefix(name, "syscall.rawSyscallNoError") || strings.HasPrefix(name, "golang.org/x/sys/unix.RawSyscallNoError"):
|
||||
return b.createRawSyscallNoError(instr)
|
||||
case name == "runtime.supportsRecover":
|
||||
supportsRecover := uint64(0)
|
||||
if b.supportsRecover() {
|
||||
supportsRecover = 1
|
||||
}
|
||||
return llvm.ConstInt(b.ctx.Int1Type(), supportsRecover, false), nil
|
||||
supportsRecover := uint64(b.supportsRecover())
|
||||
return llvm.ConstInt(b.ctx.Int8Type(), supportsRecover, false), nil
|
||||
case name == "runtime.panicStrategy":
|
||||
// These constants are defined in src/runtime/panic.go.
|
||||
panicStrategy := map[string]uint64{
|
||||
|
||||
@@ -44,6 +44,7 @@ func TestCompiler(t *testing.T) {
|
||||
{"interface.go", "", ""},
|
||||
{"func.go", "", ""},
|
||||
{"defer.go", "cortex-m-qemu", ""},
|
||||
{"defer.go", "wasm", "none"},
|
||||
{"pragma.go", "", ""},
|
||||
{"goroutine.go", "wasm", "asyncify"},
|
||||
{"goroutine.go", "cortex-m-qemu", "tasks"},
|
||||
|
||||
+137
-34
@@ -16,34 +16,54 @@ package compiler
|
||||
import (
|
||||
"go/types"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
type recoverType uint8
|
||||
|
||||
const (
|
||||
// Note: this matches recoverSupport in src/runtime/panic.go
|
||||
recoverNone recoverType = iota
|
||||
recoverInlineAsm
|
||||
recoverWasmEH // WebAssembly exception handling
|
||||
)
|
||||
|
||||
// supportsRecover returns whether the compiler supports the recover() builtin
|
||||
// for the current architecture.
|
||||
func (b *builder) supportsRecover() bool {
|
||||
switch b.archFamily() {
|
||||
func (c *compilerContext) supportsRecover() recoverType {
|
||||
switch c.archFamily() {
|
||||
case "wasm32":
|
||||
// Probably needs to be implemented using the exception handling
|
||||
// proposal of WebAssembly:
|
||||
// https://github.com/WebAssembly/exception-handling
|
||||
return false
|
||||
if !strings.Contains(c.Features, "+exception-handling") {
|
||||
// No support for the exception handling proposal.
|
||||
return recoverNone
|
||||
}
|
||||
if c.Scheduler == "asyncify" {
|
||||
// Asyncify does not support WebAssembly exception handling.
|
||||
// It exits with the following message:
|
||||
// unexpected expression type
|
||||
// UNREACHABLE executed at $TINYGOROOT/lib/binaryen/src/passes/Asyncify.cpp:1142!
|
||||
// See: https://github.com/WebAssembly/binaryen/issues/4470
|
||||
return recoverNone
|
||||
}
|
||||
// Use WebAssembly exception handling.
|
||||
return recoverWasmEH
|
||||
case "riscv64", "xtensa":
|
||||
// TODO: add support for these architectures
|
||||
return false
|
||||
return recoverNone
|
||||
default:
|
||||
return true
|
||||
return recoverInlineAsm
|
||||
}
|
||||
}
|
||||
|
||||
// hasDeferFrame returns whether the current function needs to catch panics and
|
||||
// run defers.
|
||||
func (b *builder) hasDeferFrame() bool {
|
||||
// deferFrameType returns the defer type for this function. It is always
|
||||
// recoverNone for functions without defer.
|
||||
func (b *builder) deferFrameType() recoverType {
|
||||
if b.fn.Recover == nil {
|
||||
return false
|
||||
return recoverNone
|
||||
}
|
||||
return b.supportsRecover()
|
||||
}
|
||||
@@ -63,21 +83,40 @@ func (b *builder) deferInitFunc() {
|
||||
b.deferPtr = b.CreateAlloca(b.dataPtrType, "deferPtr")
|
||||
b.CreateStore(llvm.ConstPointerNull(b.dataPtrType), b.deferPtr)
|
||||
|
||||
if b.hasDeferFrame() {
|
||||
switch b.deferFrameType() {
|
||||
case recoverInlineAsm:
|
||||
// Set up the defer frame with the current stack pointer.
|
||||
// This assumes that the stack pointer doesn't move outside of the
|
||||
// function prologue/epilogue (an invariant maintained by TinyGo but
|
||||
// possibly broken by the C alloca function).
|
||||
// The frame pointer is _not_ saved, because it is marked as clobbered
|
||||
// in the setjmp-like inline assembly.
|
||||
deferFrameType := b.getLLVMRuntimeType("deferFrame")
|
||||
deferFrameType := b.getLLVMRuntimeType("deferFrameInlineAsm")
|
||||
b.deferFrame = b.CreateAlloca(deferFrameType, "deferframe.buf")
|
||||
stackPointer := b.readStackPointer()
|
||||
b.createRuntimeCall("setupDeferFrame", []llvm.Value{b.deferFrame, stackPointer}, "")
|
||||
b.createRuntimeCall("setupDeferFrameInlineAsm", []llvm.Value{b.deferFrame, stackPointer}, "")
|
||||
|
||||
// Create the landing pad block, which is where control transfers after
|
||||
// a panic.
|
||||
b.landingpad = b.ctx.AddBasicBlock(b.llvmFn, "lpad")
|
||||
case recoverWasmEH:
|
||||
// Set a personality function, which is required by LLVM but not
|
||||
// actually called. __gxx_wasm_personality_v0 is the only one that is
|
||||
// acceptable to the WebAssembly backend it seems.
|
||||
personality := b.mod.NamedFunction("__gxx_wasm_personality_v0")
|
||||
if personality.IsNil() {
|
||||
fnType := llvm.FunctionType(b.ctx.Int32Type(), nil, true)
|
||||
personality = llvm.AddFunction(b.mod, "__gxx_wasm_personality_v0", fnType)
|
||||
}
|
||||
b.llvmFn.SetPersonality(personality)
|
||||
|
||||
// Set up the defer frame.
|
||||
deferFrameType := b.getLLVMRuntimeType("deferFrameWasmEH")
|
||||
b.deferFrame = b.CreateAlloca(deferFrameType, "deferframe.buf")
|
||||
b.createRuntimeCall("setupDeferFrameWasmEH", []llvm.Value{b.deferFrame}, "")
|
||||
|
||||
// Create the landing pad where the 'throw' instruction will jump to.
|
||||
b.landingpad = b.ctx.AddBasicBlock(b.llvmFn, "catch.dispatch")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +134,43 @@ func (b *builder) createLandingPad() {
|
||||
b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), b.difunc, llvm.Metadata{})
|
||||
}
|
||||
|
||||
if b.supportsRecover() == recoverWasmEH {
|
||||
// Insert exception handling instructions.
|
||||
// This emulates C++ exceptions, as if every function is wrapped like
|
||||
// this:
|
||||
//
|
||||
// try {
|
||||
// function body
|
||||
// } catch (...) {
|
||||
// run all defers
|
||||
// }
|
||||
// if deferFrame.Panicking {
|
||||
// // re-raise the same panic message
|
||||
// panic(previousPanic)
|
||||
// }
|
||||
//
|
||||
// This means that if there is a C++ exception in the program, it will
|
||||
// get eaten by the Go code. This is fixable if needed (by checking
|
||||
// whether it's actually a TinyGo exception and re-raising the same
|
||||
// exception if it isn't after running deferred functions).
|
||||
// For more information about C++ exception support in WebAssembly:
|
||||
// https://github.com/WebAssembly/tool-conventions/blob/main/EHScheme.md
|
||||
|
||||
// basic block: catch.dispatch
|
||||
catchStartBB := b.insertBasicBlock("catch.start")
|
||||
catchswitch := b.CreateCatchSwitch(llvm.Value{}, llvm.BasicBlock{}, 1, "")
|
||||
catchswitch.AddHandler(catchStartBB)
|
||||
|
||||
// basic block: catch.start
|
||||
b.SetInsertPointAtEnd(catchStartBB)
|
||||
catchpad := b.CreateCatchPad(catchswitch, []llvm.Value{llvm.ConstNull(b.dataPtrType)}, "")
|
||||
rundefersBB := b.insertBasicBlock("rundefers")
|
||||
b.CreateCatchRet(catchpad, rundefersBB)
|
||||
|
||||
// basic block: rundefers
|
||||
b.SetInsertPointAtEnd(rundefersBB)
|
||||
}
|
||||
|
||||
b.createRunDefers()
|
||||
|
||||
// Continue at the 'recover' block, which returns to the parent in an
|
||||
@@ -432,11 +508,25 @@ func (b *builder) createRunDefers() {
|
||||
// }
|
||||
// }
|
||||
|
||||
// Create loop, in the order: loophead, loop, callback0, callback1, ..., unreachable, end.
|
||||
// Create loop, in the order:
|
||||
// - loophead
|
||||
// - loop
|
||||
// - callback0
|
||||
// - callback1
|
||||
// - callback*
|
||||
// - unreachable
|
||||
// - catch.dispatch (if wasm EH)
|
||||
// - catch.start (if wasm EH)
|
||||
// - end
|
||||
var catchDispatch, catchStart llvm.BasicBlock
|
||||
end := b.insertBasicBlock("rundefers.end")
|
||||
unreachable := b.ctx.InsertBasicBlock(end, "rundefers.default")
|
||||
loop := b.ctx.InsertBasicBlock(unreachable, "rundefers.loop")
|
||||
loophead := b.ctx.InsertBasicBlock(loop, "rundefers.loophead")
|
||||
if b.supportsRecover() == recoverWasmEH {
|
||||
catchDispatch = b.ctx.InsertBasicBlock(end, "rundefers.catch.dispatch")
|
||||
catchStart = b.ctx.InsertBasicBlock(end, "rundefers.catch.start")
|
||||
}
|
||||
b.CreateBr(loophead)
|
||||
|
||||
// Create loop head:
|
||||
@@ -471,6 +561,9 @@ func (b *builder) createRunDefers() {
|
||||
block := b.insertBasicBlock("rundefers.callback" + strconv.Itoa(i))
|
||||
sw.AddCase(llvm.ConstInt(b.uintptrType, uint64(i), false), block)
|
||||
b.SetInsertPointAtEnd(block)
|
||||
var fnType llvm.Type
|
||||
var llvmFn llvm.Value
|
||||
var forwardParams []llvm.Value
|
||||
switch callback := callback.(type) {
|
||||
case *ssa.CallCommon:
|
||||
// Call on an value or interface value.
|
||||
@@ -491,7 +584,6 @@ func (b *builder) createRunDefers() {
|
||||
}
|
||||
|
||||
// Extract the params from the struct (including receiver).
|
||||
forwardParams := []llvm.Value{}
|
||||
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
|
||||
deferredCallType := b.ctx.StructType(valueTypes, false)
|
||||
for i := 2; i < len(valueTypes); i++ {
|
||||
@@ -500,9 +592,6 @@ func (b *builder) createRunDefers() {
|
||||
forwardParams = append(forwardParams, forwardParam)
|
||||
}
|
||||
|
||||
var fnPtr llvm.Value
|
||||
var fnType llvm.Type
|
||||
|
||||
if !callback.IsInvoke() {
|
||||
// Isolate the func value.
|
||||
funcValue := forwardParams[0]
|
||||
@@ -510,7 +599,7 @@ func (b *builder) createRunDefers() {
|
||||
|
||||
//Get function pointer and context
|
||||
var context llvm.Value
|
||||
fnPtr, context = b.decodeFuncValue(funcValue)
|
||||
llvmFn, context = b.decodeFuncValue(funcValue)
|
||||
fnType = b.getLLVMFunctionType(callback.Signature())
|
||||
|
||||
//Pass context
|
||||
@@ -519,8 +608,8 @@ func (b *builder) createRunDefers() {
|
||||
// Move typecode from the start to the end of the list of
|
||||
// parameters.
|
||||
forwardParams = append(forwardParams[1:], forwardParams[0])
|
||||
fnPtr = b.getInvokeFunction(callback)
|
||||
fnType = fnPtr.GlobalValueType()
|
||||
llvmFn = b.getInvokeFunction(callback)
|
||||
fnType = llvmFn.GlobalValueType()
|
||||
|
||||
// Add the context parameter. An interface call cannot also be a
|
||||
// closure but we have to supply the parameter anyway for platforms
|
||||
@@ -528,8 +617,6 @@ func (b *builder) createRunDefers() {
|
||||
forwardParams = append(forwardParams, llvm.Undef(b.dataPtrType))
|
||||
}
|
||||
|
||||
b.createCall(fnType, fnPtr, forwardParams, "")
|
||||
|
||||
case *ssa.Function:
|
||||
// Direct call.
|
||||
|
||||
@@ -541,7 +628,6 @@ func (b *builder) createRunDefers() {
|
||||
deferredCallType := b.ctx.StructType(valueTypes, false)
|
||||
|
||||
// Extract the params from the struct.
|
||||
forwardParams := []llvm.Value{}
|
||||
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
|
||||
for i := range getParams(callback.Signature) {
|
||||
gep := b.CreateInBoundsGEP(deferredCallType, deferData, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
|
||||
@@ -557,9 +643,7 @@ func (b *builder) createRunDefers() {
|
||||
forwardParams = append(forwardParams, llvm.Undef(b.dataPtrType))
|
||||
}
|
||||
|
||||
// Call real function.
|
||||
fnType, fn := b.getFunction(callback)
|
||||
b.createInvoke(fnType, fn, forwardParams, "")
|
||||
fnType, llvmFn = b.getFunction(callback)
|
||||
|
||||
case *ssa.MakeClosure:
|
||||
// Get the real defer struct type and cast to it.
|
||||
@@ -573,7 +657,6 @@ func (b *builder) createRunDefers() {
|
||||
deferredCallType := b.ctx.StructType(valueTypes, false)
|
||||
|
||||
// Extract the params from the struct.
|
||||
forwardParams := []llvm.Value{}
|
||||
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
|
||||
for i := 2; i < len(valueTypes); i++ {
|
||||
gep := b.CreateInBoundsGEP(deferredCallType, deferData, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "")
|
||||
@@ -582,8 +665,7 @@ func (b *builder) createRunDefers() {
|
||||
}
|
||||
|
||||
// Call deferred function.
|
||||
fnType, llvmFn := b.getFunction(fn)
|
||||
b.createCall(fnType, llvmFn, forwardParams, "")
|
||||
fnType, llvmFn = b.getFunction(fn)
|
||||
case *ssa.Builtin:
|
||||
db := b.deferBuiltinFuncs[callback]
|
||||
|
||||
@@ -611,12 +693,20 @@ func (b *builder) createRunDefers() {
|
||||
if err != nil {
|
||||
b.diagnostics = append(b.diagnostics, err)
|
||||
}
|
||||
b.CreateBr(loophead)
|
||||
continue
|
||||
default:
|
||||
panic("unknown deferred function type")
|
||||
}
|
||||
|
||||
// Branch back to the start of the loop.
|
||||
b.CreateBr(loophead)
|
||||
// Call the deferred function.
|
||||
if b.supportsRecover() == recoverWasmEH {
|
||||
b.CreateInvoke(fnType, llvmFn, b.expandFormalParams(forwardParams), loophead, catchDispatch, "")
|
||||
} else {
|
||||
b.createInvoke(fnType, llvmFn, forwardParams, "")
|
||||
// Branch back to the start of the loop.
|
||||
b.CreateBr(loophead)
|
||||
}
|
||||
}
|
||||
|
||||
// Create default unreachable block:
|
||||
@@ -626,6 +716,19 @@ func (b *builder) createRunDefers() {
|
||||
b.SetInsertPointAtEnd(unreachable)
|
||||
b.CreateUnreachable()
|
||||
|
||||
// Ignore any exception that might have occured while running the deferred
|
||||
// functions. The compiler will insert a check whether the function is still
|
||||
// panicking before return, so no panic gets lost.
|
||||
if b.supportsRecover() == recoverWasmEH {
|
||||
b.SetInsertPointAtEnd(catchDispatch)
|
||||
catchswitch := b.CreateCatchSwitch(llvm.Value{}, llvm.BasicBlock{}, 1, "")
|
||||
catchswitch.AddHandler(catchStart)
|
||||
|
||||
b.SetInsertPointAtEnd(catchStart)
|
||||
catchpad := b.CreateCatchPad(catchswitch, []llvm.Value{llvm.ConstNull(b.dataPtrType)}, "")
|
||||
b.CreateCatchRet(catchpad, loophead)
|
||||
}
|
||||
|
||||
// End of loop.
|
||||
b.SetInsertPointAtEnd(end)
|
||||
}
|
||||
|
||||
+4
-1
@@ -174,6 +174,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
// that the only thing we'll do is read the pointer.
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nounwind"), 0))
|
||||
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
|
||||
if strings.Split(c.Triple, "-")[0] == "avr" {
|
||||
// These functions are compiler-rt/libgcc functions that are
|
||||
@@ -470,7 +471,9 @@ func (c *compilerContext) addStandardDefinedAttributes(llvmFn llvm.Value) {
|
||||
// This behavior matches Clang when compiling C source files.
|
||||
// It reduces binary size on Linux a little bit on non-x86_64 targets by
|
||||
// eliminating exception tables for these functions.
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nounwind"), 0))
|
||||
if c.supportsRecover() != recoverWasmEH {
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nounwind"), 0))
|
||||
}
|
||||
if strings.Split(c.Triple, "-")[0] == "x86_64" {
|
||||
// Required by the ABI.
|
||||
// The uwtable has two possible values: sync (1) or async (2). We use
|
||||
|
||||
Vendored
+25
-24
@@ -13,30 +13,31 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.addInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.addInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = add i32 %x, %y
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.equalInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.equalInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.divInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.divInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
@@ -54,10 +55,10 @@ divbyzero.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.divideByZeroPanic(ptr) #1
|
||||
declare void @runtime.divideByZeroPanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
@@ -72,7 +73,7 @@ divbyzero.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
@@ -91,7 +92,7 @@ divbyzero.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq i32 %y, 0
|
||||
br i1 %0, label %divbyzero.throw, label %divbyzero.next
|
||||
@@ -106,61 +107,61 @@ divbyzero.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp oeq float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatNE(float %x, float %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.floatNE(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp une float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatLower(float %x, float %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.floatLower(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp olt float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatLowerEqual(float %x, float %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.floatLowerEqual(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp ole float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatGreater(float %x, float %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.floatGreater(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp ogt float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.floatGreaterEqual(float %x, float %y, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.floatGreaterEqual(float %x, float %y, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp oge float %x, %y
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.complexReal(float %x.r, float %x.i, ptr %context) unnamed_addr #2 {
|
||||
define hidden float @main.complexReal(float %x.r, float %x.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret float %x.r
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.complexImag(float %x.r, float %x.i, ptr %context) unnamed_addr #2 {
|
||||
define hidden float @main.complexImag(float %x.r, float %x.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret float %x.i
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #2 {
|
||||
define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fadd float %x.r, %y.r
|
||||
%1 = fadd float %x.i, %y.i
|
||||
@@ -170,7 +171,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #2 {
|
||||
define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fsub float %x.r, %y.r
|
||||
%1 = fsub float %x.i, %y.i
|
||||
@@ -180,7 +181,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #2 {
|
||||
define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fmul float %x.r, %y.r
|
||||
%1 = fmul float %x.i, %y.i
|
||||
@@ -194,19 +195,19 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.foo(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.foo(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #2 {
|
||||
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+16
-15
@@ -9,16 +9,17 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanIntSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.chanIntSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
%chan.value = alloca i32, align 4
|
||||
@@ -32,15 +33,15 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2
|
||||
|
||||
declare void @runtime.chanSend(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #1
|
||||
declare void @runtime.chanSend(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #3
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
%chan.value = alloca i32, align 4
|
||||
@@ -52,10 +53,10 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #1
|
||||
declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #3
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
@@ -65,7 +66,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||
@@ -75,7 +76,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(32) %ch1, ptr dereferenceable_or_null(32) %ch2, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(32) %ch1, ptr dereferenceable_or_null(32) %ch2, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%select.states.alloca = alloca [2 x %runtime.chanSelectState], align 8
|
||||
%select.send.value = alloca i32, align 4
|
||||
@@ -105,10 +106,10 @@ select.body: ; preds = %select.next
|
||||
br label %select.done
|
||||
}
|
||||
|
||||
declare { i32, i1 } @runtime.tryChanSelect(ptr, ptr, i32, i32, ptr) #1
|
||||
declare { i32, i1 } @runtime.tryChanSelect(ptr, ptr, i32, i32, ptr) #3
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
attributes #3 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #4 = { nounwind }
|
||||
|
||||
+11
-11
@@ -3,7 +3,7 @@ source_filename = "defer.go"
|
||||
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
target triple = "thumbv7m-unknown-unknown-eabi"
|
||||
|
||||
%runtime.deferFrame = type { ptr, ptr, [0 x ptr], ptr, i1, %runtime._interface }
|
||||
%runtime.deferFrameInlineAsm = type { ptr, ptr, [0 x ptr], ptr, i1, %runtime._interface }
|
||||
%runtime._interface = type { ptr, ptr }
|
||||
%runtime._defer = type { i32, ptr }
|
||||
|
||||
@@ -24,9 +24,9 @@ entry:
|
||||
%defer.alloca = alloca { i32, ptr }, align 4
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrameInlineAsm, align 4
|
||||
%0 = call ptr @llvm.stacksave.p0()
|
||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||
call void @runtime.setupDeferFrameInlineAsm(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
store ptr null, ptr %defer.alloca.repack15, align 4
|
||||
@@ -40,7 +40,7 @@ entry:
|
||||
br label %rundefers.block
|
||||
|
||||
rundefers.after: ; preds = %rundefers.end
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
call void @runtime.destroyDeferFrameInlineAsm(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
ret void
|
||||
|
||||
rundefers.block: ; preds = %1
|
||||
@@ -76,7 +76,7 @@ rundefers.end: ; preds = %rundefers.loophead
|
||||
br label %rundefers.after
|
||||
|
||||
recover: ; preds = %rundefers.end3
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
call void @runtime.destroyDeferFrameInlineAsm(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
ret void
|
||||
|
||||
lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry
|
||||
@@ -115,9 +115,9 @@ rundefers.end3: ; preds = %rundefers.loophead6
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn
|
||||
declare ptr @llvm.stacksave.p0() #3
|
||||
|
||||
declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #2
|
||||
declare void @runtime.setupDeferFrameInlineAsm(ptr dereferenceable_or_null(24), ptr, ptr) #2
|
||||
|
||||
declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #2
|
||||
declare void @runtime.destroyDeferFrameInlineAsm(ptr dereferenceable_or_null(24), ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 {
|
||||
@@ -135,9 +135,9 @@ entry:
|
||||
%defer.alloca = alloca { i32, ptr }, align 4
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrameInlineAsm, align 4
|
||||
%0 = call ptr @llvm.stacksave.p0()
|
||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||
call void @runtime.setupDeferFrameInlineAsm(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
store ptr null, ptr %defer.alloca.repack22, align 4
|
||||
@@ -155,7 +155,7 @@ entry:
|
||||
br label %rundefers.block
|
||||
|
||||
rundefers.after: ; preds = %rundefers.end
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
call void @runtime.destroyDeferFrameInlineAsm(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
ret void
|
||||
|
||||
rundefers.block: ; preds = %1
|
||||
@@ -201,7 +201,7 @@ rundefers.end: ; preds = %rundefers.loophead
|
||||
br label %rundefers.after
|
||||
|
||||
recover: ; preds = %rundefers.end7
|
||||
call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
call void @runtime.destroyDeferFrameInlineAsm(ptr nonnull %deferframe.buf, ptr undef) #4
|
||||
ret void
|
||||
|
||||
lpad: ; preds = %rundefers.callback119, %rundefers.callback016, %rundefers.callback1, %rundefers.callback0, %entry
|
||||
|
||||
Vendored
+273
@@ -0,0 +1,273 @@
|
||||
; ModuleID = 'defer.go'
|
||||
source_filename = "defer.go"
|
||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||
target triple = "wasm32-unknown-wasi"
|
||||
|
||||
%runtime.deferFrameWasmEH = type { ptr, i1, %runtime._interface }
|
||||
%runtime._interface = type { ptr, ptr }
|
||||
%runtime._defer = type { i32, ptr }
|
||||
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @main.external(ptr) #2
|
||||
|
||||
define hidden void @main.deferSimple(ptr %context) unnamed_addr #2 personality ptr @__gxx_wasm_personality_v0 {
|
||||
entry:
|
||||
%defer.alloca = alloca { i32, ptr }, align 8
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrameWasmEH, align 8
|
||||
call void @runtime.setupDeferFrameWasmEH(ptr nonnull %deferframe.buf, ptr undef)
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr nonnull %defer.alloca, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack13 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
store ptr null, ptr %defer.alloca.repack13, align 4
|
||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||
invoke void @main.external(ptr undef)
|
||||
to label %invoke.cont unwind label %catch.dispatch
|
||||
|
||||
invoke.cont: ; preds = %entry
|
||||
br label %rundefers.block
|
||||
|
||||
rundefers.after: ; preds = %rundefers.end
|
||||
call void @runtime.destroyDeferFrameWasmEH(ptr nonnull %deferframe.buf, ptr undef)
|
||||
ret void
|
||||
|
||||
rundefers.block: ; preds = %invoke.cont
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.loophead: ; preds = %rundefers.catch.start, %rundefers.callback0, %rundefers.block
|
||||
%0 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil = icmp eq ptr %0, null
|
||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||
|
||||
rundefers.loop: ; preds = %rundefers.loophead
|
||||
%stack.next.gep = getelementptr inbounds %runtime._defer, ptr %0, i32 0, i32 1
|
||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||
store ptr %stack.next, ptr %deferPtr, align 4
|
||||
%callback = load i32, ptr %0, align 4
|
||||
switch i32 %callback, label %rundefers.default [
|
||||
i32 0, label %rundefers.callback0
|
||||
]
|
||||
|
||||
rundefers.callback0: ; preds = %rundefers.loop
|
||||
invoke void @"main.deferSimple$1"(ptr undef)
|
||||
to label %rundefers.loophead unwind label %rundefers.catch.dispatch
|
||||
|
||||
rundefers.default: ; preds = %rundefers.loop
|
||||
unreachable
|
||||
|
||||
rundefers.catch.dispatch: ; preds = %rundefers.callback0
|
||||
%1 = catchswitch within none [label %rundefers.catch.start] unwind to caller
|
||||
|
||||
rundefers.catch.start: ; preds = %rundefers.catch.dispatch
|
||||
%2 = catchpad within %1 [ptr null]
|
||||
catchret from %2 to label %rundefers.loophead
|
||||
|
||||
rundefers.end: ; preds = %rundefers.loophead
|
||||
br label %rundefers.after
|
||||
|
||||
recover: ; preds = %rundefers.end1
|
||||
call void @runtime.destroyDeferFrameWasmEH(ptr nonnull %deferframe.buf, ptr undef)
|
||||
ret void
|
||||
|
||||
catch.dispatch: ; preds = %entry
|
||||
%3 = catchswitch within none [label %catch.start] unwind to caller
|
||||
|
||||
catch.start: ; preds = %catch.dispatch
|
||||
%4 = catchpad within %3 [ptr null]
|
||||
catchret from %4 to label %rundefers
|
||||
|
||||
rundefers: ; preds = %catch.start
|
||||
br label %rundefers.loophead4
|
||||
|
||||
rundefers.loophead4: ; preds = %rundefers.catch.start6, %rundefers.callback012, %rundefers
|
||||
%5 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil7 = icmp eq ptr %5, null
|
||||
br i1 %stackIsNil7, label %rundefers.end1, label %rundefers.loop3
|
||||
|
||||
rundefers.loop3: ; preds = %rundefers.loophead4
|
||||
%stack.next.gep8 = getelementptr inbounds %runtime._defer, ptr %5, i32 0, i32 1
|
||||
%stack.next9 = load ptr, ptr %stack.next.gep8, align 4
|
||||
store ptr %stack.next9, ptr %deferPtr, align 4
|
||||
%callback11 = load i32, ptr %5, align 4
|
||||
switch i32 %callback11, label %rundefers.default2 [
|
||||
i32 0, label %rundefers.callback012
|
||||
]
|
||||
|
||||
rundefers.callback012: ; preds = %rundefers.loop3
|
||||
invoke void @"main.deferSimple$1"(ptr undef)
|
||||
to label %rundefers.loophead4 unwind label %rundefers.catch.dispatch5
|
||||
|
||||
rundefers.default2: ; preds = %rundefers.loop3
|
||||
unreachable
|
||||
|
||||
rundefers.catch.dispatch5: ; preds = %rundefers.callback012
|
||||
%6 = catchswitch within none [label %rundefers.catch.start6] unwind to caller
|
||||
|
||||
rundefers.catch.start6: ; preds = %rundefers.catch.dispatch5
|
||||
%7 = catchpad within %6 [ptr null]
|
||||
catchret from %7 to label %rundefers.loophead4
|
||||
|
||||
rundefers.end1: ; preds = %rundefers.loophead4
|
||||
br label %recover
|
||||
}
|
||||
|
||||
declare i32 @__gxx_wasm_personality_v0(...)
|
||||
|
||||
declare void @runtime.setupDeferFrameWasmEH(ptr dereferenceable_or_null(16), ptr) #2
|
||||
|
||||
declare void @runtime.destroyDeferFrameWasmEH(ptr dereferenceable_or_null(16), ptr) #2
|
||||
|
||||
define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 3, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.printint32(i32, ptr) #2
|
||||
|
||||
define hidden void @main.deferMultiple(ptr %context) unnamed_addr #2 personality ptr @__gxx_wasm_personality_v0 {
|
||||
entry:
|
||||
%defer.alloca2 = alloca { i32, ptr }, align 8
|
||||
%defer.alloca = alloca { i32, ptr }, align 8
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrameWasmEH, align 8
|
||||
call void @runtime.setupDeferFrameWasmEH(ptr nonnull %deferframe.buf, ptr undef)
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr nonnull %defer.alloca, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack16 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
store ptr null, ptr %defer.alloca.repack16, align 4
|
||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||
call void @runtime.trackPointer(ptr nonnull %defer.alloca2, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 1, ptr %defer.alloca2, align 4
|
||||
%defer.alloca2.repack17 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca2, i32 0, i32 1
|
||||
store ptr %defer.alloca, ptr %defer.alloca2.repack17, align 4
|
||||
store ptr %defer.alloca2, ptr %deferPtr, align 4
|
||||
invoke void @main.external(ptr undef)
|
||||
to label %invoke.cont unwind label %catch.dispatch
|
||||
|
||||
invoke.cont: ; preds = %entry
|
||||
br label %rundefers.block
|
||||
|
||||
rundefers.after: ; preds = %rundefers.end
|
||||
call void @runtime.destroyDeferFrameWasmEH(ptr nonnull %deferframe.buf, ptr undef)
|
||||
ret void
|
||||
|
||||
rundefers.block: ; preds = %invoke.cont
|
||||
br label %rundefers.loophead
|
||||
|
||||
rundefers.loophead: ; preds = %rundefers.catch.start, %rundefers.callback1, %rundefers.callback0, %rundefers.block
|
||||
%0 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil = icmp eq ptr %0, null
|
||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||
|
||||
rundefers.loop: ; preds = %rundefers.loophead
|
||||
%stack.next.gep = getelementptr inbounds %runtime._defer, ptr %0, i32 0, i32 1
|
||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||
store ptr %stack.next, ptr %deferPtr, align 4
|
||||
%callback = load i32, ptr %0, align 4
|
||||
switch i32 %callback, label %rundefers.default [
|
||||
i32 0, label %rundefers.callback0
|
||||
i32 1, label %rundefers.callback1
|
||||
]
|
||||
|
||||
rundefers.callback0: ; preds = %rundefers.loop
|
||||
invoke void @"main.deferMultiple$1"(ptr undef)
|
||||
to label %rundefers.loophead unwind label %rundefers.catch.dispatch
|
||||
|
||||
rundefers.callback1: ; preds = %rundefers.loop
|
||||
invoke void @"main.deferMultiple$2"(ptr undef)
|
||||
to label %rundefers.loophead unwind label %rundefers.catch.dispatch
|
||||
|
||||
rundefers.default: ; preds = %rundefers.loop
|
||||
unreachable
|
||||
|
||||
rundefers.catch.dispatch: ; preds = %rundefers.callback1, %rundefers.callback0
|
||||
%1 = catchswitch within none [label %rundefers.catch.start] unwind to caller
|
||||
|
||||
rundefers.catch.start: ; preds = %rundefers.catch.dispatch
|
||||
%2 = catchpad within %1 [ptr null]
|
||||
catchret from %2 to label %rundefers.loophead
|
||||
|
||||
rundefers.end: ; preds = %rundefers.loophead
|
||||
br label %rundefers.after
|
||||
|
||||
recover: ; preds = %rundefers.end3
|
||||
call void @runtime.destroyDeferFrameWasmEH(ptr nonnull %deferframe.buf, ptr undef)
|
||||
ret void
|
||||
|
||||
catch.dispatch: ; preds = %entry
|
||||
%3 = catchswitch within none [label %catch.start] unwind to caller
|
||||
|
||||
catch.start: ; preds = %catch.dispatch
|
||||
%4 = catchpad within %3 [ptr null]
|
||||
catchret from %4 to label %rundefers
|
||||
|
||||
rundefers: ; preds = %catch.start
|
||||
br label %rundefers.loophead6
|
||||
|
||||
rundefers.loophead6: ; preds = %rundefers.catch.start8, %rundefers.callback115, %rundefers.callback014, %rundefers
|
||||
%5 = load ptr, ptr %deferPtr, align 4
|
||||
%stackIsNil9 = icmp eq ptr %5, null
|
||||
br i1 %stackIsNil9, label %rundefers.end3, label %rundefers.loop5
|
||||
|
||||
rundefers.loop5: ; preds = %rundefers.loophead6
|
||||
%stack.next.gep10 = getelementptr inbounds %runtime._defer, ptr %5, i32 0, i32 1
|
||||
%stack.next11 = load ptr, ptr %stack.next.gep10, align 4
|
||||
store ptr %stack.next11, ptr %deferPtr, align 4
|
||||
%callback13 = load i32, ptr %5, align 4
|
||||
switch i32 %callback13, label %rundefers.default4 [
|
||||
i32 0, label %rundefers.callback014
|
||||
i32 1, label %rundefers.callback115
|
||||
]
|
||||
|
||||
rundefers.callback014: ; preds = %rundefers.loop5
|
||||
invoke void @"main.deferMultiple$1"(ptr undef)
|
||||
to label %rundefers.loophead6 unwind label %rundefers.catch.dispatch7
|
||||
|
||||
rundefers.callback115: ; preds = %rundefers.loop5
|
||||
invoke void @"main.deferMultiple$2"(ptr undef)
|
||||
to label %rundefers.loophead6 unwind label %rundefers.catch.dispatch7
|
||||
|
||||
rundefers.default4: ; preds = %rundefers.loop5
|
||||
unreachable
|
||||
|
||||
rundefers.catch.dispatch7: ; preds = %rundefers.callback115, %rundefers.callback014
|
||||
%6 = catchswitch within none [label %rundefers.catch.start8] unwind to caller
|
||||
|
||||
rundefers.catch.start8: ; preds = %rundefers.catch.dispatch7
|
||||
%7 = catchpad within %6 [ptr null]
|
||||
catchret from %7 to label %rundefers.loophead6
|
||||
|
||||
rundefers.end3: ; preds = %rundefers.loophead6
|
||||
br label %recover
|
||||
}
|
||||
|
||||
define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 3, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 5, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
Vendored
+12
-12
@@ -6,16 +6,17 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.f32tou32(float %v, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.f32tou32(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%positive = fcmp oge float %v, 0.000000e+00
|
||||
%withinmax = fcmp ole float %v, 0x41EFFFFFC0000000
|
||||
@@ -27,25 +28,25 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.maxu32f(ptr %context) unnamed_addr #2 {
|
||||
define hidden float @main.maxu32f(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret float 0x41F0000000000000
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.maxu32tof32(ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.maxu32tof32(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 -1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { i32, i32, i32, i32 } @main.inftoi32(ptr %context) unnamed_addr #2 {
|
||||
define hidden { i32, i32, i32, i32 } @main.inftoi32(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret { i32, i32, i32, i32 } { i32 -1, i32 0, i32 2147483647, i32 -2147483648 }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.u32tof32tou32(i32 %v, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.u32tof32tou32(i32 %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = uitofp i32 %v to float
|
||||
%withinmax = fcmp ole float %0, 0x41EFFFFFC0000000
|
||||
@@ -55,7 +56,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.f32tou32tof32(float %v, ptr %context) unnamed_addr #2 {
|
||||
define hidden float @main.f32tou32tof32(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%positive = fcmp oge float %v, 0.000000e+00
|
||||
%withinmax = fcmp ole float %v, 0x41EFFFFFC0000000
|
||||
@@ -68,7 +69,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.f32tou8(float %v, ptr %context) unnamed_addr #2 {
|
||||
define hidden i8 @main.f32tou8(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%positive = fcmp oge float %v, 0.000000e+00
|
||||
%withinmax = fcmp ole float %v, 2.550000e+02
|
||||
@@ -80,7 +81,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.f32toi8(float %v, ptr %context) unnamed_addr #2 {
|
||||
define hidden i8 @main.f32toi8(float %v, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%abovemin = fcmp oge float %v, -1.280000e+02
|
||||
%belowmax = fcmp ole float %v, 1.270000e+02
|
||||
@@ -93,6 +94,5 @@ entry:
|
||||
ret i8 %0
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
|
||||
Vendored
+9
-8
@@ -6,16 +6,17 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.foo(ptr %callback.context, ptr %callback.funcptr, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.foo(ptr %callback.context, ptr %callback.funcptr, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp eq ptr %callback.funcptr, null
|
||||
br i1 %0, label %fpcall.throw, label %fpcall.next
|
||||
@@ -29,22 +30,22 @@ fpcall.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.nilPanic(ptr) #1
|
||||
declare void @runtime.nilPanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.bar(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.bar(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @main.foo(ptr undef, ptr nonnull @main.someFunc, ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.someFunc(i32 %arg0, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.someFunc(i32 %arg0, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+45
-45
@@ -27,93 +27,94 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.newScalar(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.newScalar(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%new = call align 1 dereferenceable(1) ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new = call align 1 dereferenceable(1) ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new, ptr @main.scalar1, align 4
|
||||
%new1 = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new1 = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new1, ptr @main.scalar2, align 4
|
||||
%new2 = call align 8 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new2 = call align 8 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new2, ptr @main.scalar3, align 4
|
||||
%new3 = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new3 = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new3, ptr @main.scalar4, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.newArray(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.newArray(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%new = call align 1 dereferenceable(3) ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new = call align 1 dereferenceable(3) ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new, ptr @main.array1, align 4
|
||||
%new1 = call align 1 dereferenceable(71) ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new1 = call align 1 dereferenceable(71) ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new1, ptr @main.array2, align 4
|
||||
%new2 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new2 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new2, ptr @main.array3, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.newStruct(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.newStruct(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%new = call align 1 ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new = call align 1 ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new, ptr @main.struct1, align 4
|
||||
%new1 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new1 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new1, ptr @main.struct2, align 4
|
||||
%new2 = call align 4 dereferenceable(248) ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new2 = call align 4 dereferenceable(248) ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new2, ptr @main.struct3, align 4
|
||||
%new3 = call align 4 dereferenceable(248) ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new3 = call align 4 dereferenceable(248) ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %new3, ptr @main.struct4, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%new = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%new = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %new
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.makeSlice(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%makeslice = call align 1 dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%makeslice = call align 1 dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %makeslice, ptr @main.slice1, align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 4
|
||||
%makeslice1 = call align 4 dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%makeslice1 = call align 4 dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %makeslice1, ptr @main.slice2, align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 4
|
||||
%makeslice3 = call align 4 dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%makeslice3 = call align 4 dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %makeslice3, ptr @main.slice3, align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 4
|
||||
@@ -121,21 +122,20 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #3
|
||||
%0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #2
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef)
|
||||
store double %v.r, ptr %0, align 8
|
||||
%.repack1 = getelementptr inbounds { double, double }, ptr %0, i32 0, i32 1
|
||||
store double %v.i, ptr %.repack1, align 8
|
||||
%1 = insertvalue %runtime._interface { ptr @"reflect/types.type:basic:complex128", ptr undef }, ptr %0, 1
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:complex128", ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:complex128", ptr nonnull %stackalloc, ptr undef)
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._interface %1
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
Vendored
+12
-11
@@ -8,24 +8,25 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %s.data
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = icmp slt i16 %len, 0
|
||||
@@ -39,7 +40,7 @@ unsafe.String.next: ; preds = %entry
|
||||
%5 = zext i16 %len to i32
|
||||
%6 = insertvalue %runtime._string undef, ptr %ptr, 0
|
||||
%7 = insertvalue %runtime._string %6, i32 %5, 1
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._string %7
|
||||
|
||||
unsafe.String.throw: ; preds = %entry
|
||||
@@ -47,17 +48,17 @@ unsafe.String.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.unsafeSlicePanic(ptr) #1
|
||||
declare void @runtime.unsafeSlicePanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.unsafeStringData(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.unsafeStringData(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %s.data
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+25
-24
@@ -8,29 +8,30 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.min1(i32 %a, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.min1(i32 %a, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.min2(i32 %a, i32 %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.min2(i32 %a, i32 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.smin.i32(i32 %a, i32 %b)
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.min3(i32 %a, i32 %b, i32 %c, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.min3(i32 %a, i32 %b, i32 %c, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.smin.i32(i32 %a, i32 %b)
|
||||
%1 = call i32 @llvm.smin.i32(i32 %0, i32 %c)
|
||||
@@ -38,7 +39,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.min4(i32 %a, i32 %b, i32 %c, i32 %d, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.min4(i32 %a, i32 %b, i32 %c, i32 %d, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.smin.i32(i32 %a, i32 %b)
|
||||
%1 = call i32 @llvm.smin.i32(i32 %0, i32 %c)
|
||||
@@ -47,21 +48,21 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.minUint8(i8 %a, i8 %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden i8 @main.minUint8(i8 %a, i8 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8 @llvm.umin.i8(i8 %a, i8 %b)
|
||||
ret i8 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.minUnsigned(i32 %a, i32 %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.minUnsigned(i32 %a, i32 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.umin.i32(i32 %a, i32 %b)
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.minFloat32(float %a, float %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden float @main.minFloat32(float %a, float %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp olt float %a, %b
|
||||
%1 = select i1 %0, float %a, float %b
|
||||
@@ -69,7 +70,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden double @main.minFloat64(double %a, double %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden double @main.minFloat64(double %a, double %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp olt double %a, %b
|
||||
%1 = select i1 %0, double %a, double %b
|
||||
@@ -77,7 +78,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.minString(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._string @main.minString(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = insertvalue %runtime._string zeroinitializer, ptr %a.data, 0
|
||||
%1 = insertvalue %runtime._string %0, i32 %a.len, 1
|
||||
@@ -87,28 +88,28 @@ entry:
|
||||
%4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #5
|
||||
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
||||
%6 = extractvalue %runtime._string %5, 0
|
||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._string %5
|
||||
}
|
||||
|
||||
declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #1
|
||||
declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.maxInt(i32 %a, i32 %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.maxInt(i32 %a, i32 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.smax.i32(i32 %a, i32 %b)
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.maxUint(i32 %a, i32 %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.maxUint(i32 %a, i32 %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i32 @llvm.umax.i32(i32 %a, i32 %b)
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden float @main.maxFloat32(float %a, float %b, ptr %context) unnamed_addr #2 {
|
||||
define hidden float @main.maxFloat32(float %a, float %b, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = fcmp ogt float %a, %b
|
||||
%1 = select i1 %0, float %a, float %b
|
||||
@@ -116,7 +117,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.maxString(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._string @main.maxString(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = insertvalue %runtime._string zeroinitializer, ptr %a.data, 0
|
||||
%1 = insertvalue %runtime._string %0, i32 %a.len, 1
|
||||
@@ -126,12 +127,12 @@ entry:
|
||||
%4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #5
|
||||
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
||||
%6 = extractvalue %runtime._string %5, 0
|
||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._string %5
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.clearSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.clearSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = shl i32 %s.len, 2
|
||||
call void @llvm.memset.p0.i32(ptr align 4 %s.data, i8 0, i32 %0, i1 false)
|
||||
@@ -142,19 +143,19 @@ entry:
|
||||
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) #3
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.clearZeroSizedSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.clearZeroSizedSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.clearMap(ptr dereferenceable_or_null(40) %m, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.clearMap(ptr dereferenceable_or_null(40) %m, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.hashmapClear(ptr %m, ptr undef) #5
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.hashmapClear(ptr dereferenceable_or_null(40), ptr) #1
|
||||
declare void @runtime.hashmapClear(ptr dereferenceable_or_null(40), ptr) #2
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
||||
declare i32 @llvm.smin.i32(i32, i32) #4
|
||||
@@ -171,9 +172,9 @@ declare i32 @llvm.smax.i32(i32, i32) #4
|
||||
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
||||
declare i32 @llvm.umax.i32(i32, i32) #4
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
attributes #5 = { nounwind }
|
||||
|
||||
+33
-32
@@ -10,24 +10,25 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 65536, ptr undef) #9
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @main.regularFunction(i32, ptr) #1
|
||||
declare void @main.regularFunction(i32, ptr) #2
|
||||
|
||||
declare void @runtime.deadlock(ptr) #1
|
||||
declare void @runtime.deadlock(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #3 {
|
||||
@@ -38,17 +39,17 @@ entry:
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @"internal/task.start"(i32, ptr, i32, ptr) #1
|
||||
declare void @"internal/task.start"(i32, ptr, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 65536, ptr undef) #9
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #2 {
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
@@ -63,16 +64,16 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%n = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 3, ptr %n, align 4
|
||||
call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr nonnull %stackalloc, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef)
|
||||
call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr nonnull %stackalloc, ptr undef)
|
||||
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 5, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr %n, ptr %1, align 4
|
||||
@@ -83,7 +84,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #2 {
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
store i32 7, ptr %context, align 4
|
||||
ret void
|
||||
@@ -100,14 +101,14 @@ entry:
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.printint32(i32, ptr) #1
|
||||
declare void @runtime.printint32(i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 5, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr %fn.context, ptr %1, align 4
|
||||
@@ -131,35 +132,35 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 1, ptr undef) #9
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #1
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.chanClose(ptr %ch, ptr undef) #9
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #1
|
||||
declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef)
|
||||
store ptr %itf.value, ptr %0, align 4
|
||||
%1 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 1
|
||||
store ptr @"main$string", ptr %1, align 4
|
||||
@@ -188,13 +189,13 @@ entry:
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="main.regularFunction" }
|
||||
attributes #4 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" }
|
||||
attributes #5 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" }
|
||||
attributes #6 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-invoke"="reflect/methods.Print(string)" "tinygo-methods"="reflect/methods.Print(string)" }
|
||||
attributes #8 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="main.regularFunction" }
|
||||
attributes #4 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" }
|
||||
attributes #5 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" }
|
||||
attributes #6 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-invoke"="reflect/methods.Print(string)" "tinygo-methods"="reflect/methods.Print(string)" }
|
||||
attributes #8 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
||||
attributes #9 = { nounwind }
|
||||
|
||||
Vendored
+28
-27
@@ -20,52 +20,53 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:int", ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:int", ptr nonnull %stackalloc, ptr undef)
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._interface { ptr @"reflect/types.type:basic:int", ptr null }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:basic:int", ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:basic:int", ptr nonnull %stackalloc, ptr undef)
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._interface { ptr @"reflect/types.type:pointer:basic:int", ptr null }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:named:error", ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:named:error", ptr nonnull %stackalloc, ptr undef)
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._interface { ptr @"reflect/types.type:pointer:named:error", ptr null }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", ptr nonnull %stackalloc, ptr undef)
|
||||
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._interface { ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", ptr null }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.isInt(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.isInt(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%typecode = call i1 @runtime.typeAssert(ptr %itf.typecode, ptr nonnull @"reflect/types.typeid:basic:int", ptr undef) #7
|
||||
br i1 %typecode, label %typeassert.ok, label %typeassert.next
|
||||
@@ -77,10 +78,10 @@ typeassert.ok: ; preds = %entry
|
||||
br label %typeassert.next
|
||||
}
|
||||
|
||||
declare i1 @runtime.typeAssert(ptr, ptr dereferenceable_or_null(1), ptr) #1
|
||||
declare i1 @runtime.typeAssert(ptr, ptr dereferenceable_or_null(1), ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.isError(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.isError(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(ptr %itf.typecode) #7
|
||||
br i1 %0, label %typeassert.ok, label %typeassert.next
|
||||
@@ -95,7 +96,7 @@ typeassert.ok: ; preds = %entry
|
||||
declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(ptr) #3
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.isStringer(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.isStringer(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(ptr %itf.typecode) #7
|
||||
br i1 %0, label %typeassert.ok, label %typeassert.next
|
||||
@@ -110,7 +111,7 @@ typeassert.ok: ; preds = %entry
|
||||
declare i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(ptr) #4
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.callFooMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 {
|
||||
define hidden i8 @main.callFooMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr %itf.value, i32 3, ptr %itf.typecode, ptr undef) #7
|
||||
ret i8 %0
|
||||
@@ -119,22 +120,22 @@ entry:
|
||||
declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr, i32, ptr, ptr) #5
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.callErrorMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._string @main.callErrorMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, ptr %itf.typecode, ptr undef) #7
|
||||
%1 = extractvalue %runtime._string %0, 0
|
||||
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #7
|
||||
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef)
|
||||
ret %runtime._string %0
|
||||
}
|
||||
|
||||
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #6
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #4 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-methods"="reflect/methods.String() string" }
|
||||
attributes #5 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" }
|
||||
attributes #6 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #4 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-methods"="reflect/methods.String() string" }
|
||||
attributes #5 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" }
|
||||
attributes #6 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #7 = { nounwind }
|
||||
|
||||
Vendored
+11
-12
@@ -6,45 +6,44 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden [0 x i32] @main.pointerDerefZero(ptr %x, ptr %context) unnamed_addr #2 {
|
||||
define hidden [0 x i32] @main.pointerDerefZero(ptr %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret [0 x i32] zeroinitializer
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
|
||||
Vendored
+16
-15
@@ -14,27 +14,28 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @extern_func() #3 {
|
||||
define void @extern_func() #2 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @somepkg.someFunction1(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @somepkg.someFunction1(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @somepkg.someFunction2(ptr) #1
|
||||
declare void @somepkg.someFunction2(ptr) #3
|
||||
|
||||
; Function Attrs: inlinehint nounwind
|
||||
define hidden void @main.inlineFunc(ptr %context) unnamed_addr #4 {
|
||||
@@ -70,15 +71,15 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @main.undefinedFunctionNotInSection(ptr) #1
|
||||
declare void @main.undefinedFunctionNotInSection(ptr) #3
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="extern_func" }
|
||||
attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exportedFunctionInSection" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-import-module"="modulename" "wasm-import-name"="import1" }
|
||||
attributes #8 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-import-module"="foobar" "wasm-import-name"="imported" }
|
||||
attributes #9 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exported" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="extern_func" }
|
||||
attributes #3 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exportedFunctionInSection" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-import-module"="modulename" "wasm-import-name"="import1" }
|
||||
attributes #8 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-import-module"="foobar" "wasm-import-name"="imported" }
|
||||
attributes #9 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exported" }
|
||||
|
||||
Vendored
+43
-42
@@ -6,28 +6,29 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceLen(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.sliceLen(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %ints.len
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceCap(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.sliceCap(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %ints.cap
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceElement(ptr %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.sliceElement(ptr %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%.not = icmp ult i32 %index, %ints.len
|
||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||
@@ -42,14 +43,14 @@ lookup.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.lookupPanic(ptr) #1
|
||||
declare void @runtime.lookupPanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%varargs = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef)
|
||||
store i32 1, ptr %varargs, align 4
|
||||
%0 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 1
|
||||
store i32 2, ptr %0, align 4
|
||||
@@ -62,14 +63,14 @@ entry:
|
||||
%2 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
||||
%3 = insertvalue { ptr, i32, i32 } %2, i32 %append.newLen, 1
|
||||
%4 = insertvalue { ptr, i32, i32 } %3, i32 %append.newCap, 2
|
||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %4
|
||||
}
|
||||
|
||||
declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr) #1
|
||||
declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr undef) #3
|
||||
@@ -79,21 +80,21 @@ entry:
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %append.newLen, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %append.newCap, 2
|
||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.sliceCopy(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.sliceCopy(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 4, ptr undef) #3
|
||||
ret i32 %copy.n
|
||||
}
|
||||
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #1
|
||||
declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%slice.maxcap = icmp slt i32 %len, 0
|
||||
@@ -104,7 +105,7 @@ slice.next: ; preds = %entry
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
@@ -112,10 +113,10 @@ slice.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.slicePanic(ptr) #1
|
||||
declare void @runtime.slicePanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%slice.maxcap = icmp slt i32 %len, 0
|
||||
@@ -127,7 +128,7 @@ slice.next: ; preds = %entry
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
@@ -136,7 +137,7 @@ slice.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%slice.maxcap = icmp ugt i32 %len, 1431655765
|
||||
@@ -148,7 +149,7 @@ slice.next: ; preds = %entry
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
@@ -157,7 +158,7 @@ slice.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%slice.maxcap = icmp ugt i32 %len, 1073741823
|
||||
@@ -169,7 +170,7 @@ slice.next: ; preds = %entry
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %2
|
||||
|
||||
slice.throw: ; preds = %entry
|
||||
@@ -178,26 +179,26 @@ slice.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = getelementptr i8, ptr %p, i32 %len
|
||||
call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %0
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = trunc i64 %len to i32
|
||||
%1 = getelementptr i8, ptr %p, i32 %0
|
||||
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef)
|
||||
ret ptr %1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.SliceToArray(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.SliceToArray(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = icmp ult i32 %s.len, 4
|
||||
br i1 %0, label %slicetoarray.throw, label %slicetoarray.next
|
||||
@@ -210,14 +211,14 @@ slicetoarray.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.sliceToArrayPointerPanic(ptr) #1
|
||||
declare void @runtime.sliceToArrayPointerPanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #2 {
|
||||
define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%makeslice = call align 4 dereferenceable(24) ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef)
|
||||
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
|
||||
|
||||
slicetoarray.next: ; preds = %entry
|
||||
@@ -228,7 +229,7 @@ slicetoarray.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = icmp ugt i32 %len, 1073741823
|
||||
@@ -242,7 +243,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||
%5 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%6 = insertvalue { ptr, i32, i32 } %5, i32 %len, 1
|
||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %len, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %7
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
@@ -250,10 +251,10 @@ unsafe.Slice.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.unsafeSlicePanic(ptr) #1
|
||||
declare void @runtime.unsafeSlicePanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = icmp eq ptr %ptr, null
|
||||
@@ -266,7 +267,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||
%4 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%5 = insertvalue { ptr, i32, i32 } %4, i32 %3, 1
|
||||
%6 = insertvalue { ptr, i32, i32 } %5, i32 %3, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %6
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
@@ -275,7 +276,7 @@ unsafe.Slice.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = icmp ugt i64 %len, 1073741823
|
||||
@@ -290,7 +291,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
||||
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %8
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
@@ -299,7 +300,7 @@ unsafe.Slice.throw: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #2 {
|
||||
define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%0 = icmp ugt i64 %len, 1073741823
|
||||
@@ -314,7 +315,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
||||
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef)
|
||||
ret { ptr, i32, i32 } %8
|
||||
|
||||
unsafe.Slice.throw: ; preds = %entry
|
||||
@@ -322,7 +323,7 @@ unsafe.Slice.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+16
-15
@@ -10,34 +10,35 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.someString(ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._string @main.someString(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret %runtime._string { ptr @"main$string", i32 3 }
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden %runtime._string @main.zeroLengthString(ptr %context) unnamed_addr #2 {
|
||||
define hidden %runtime._string @main.zeroLengthString(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret %runtime._string zeroinitializer
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i32 @main.stringLen(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden i32 @main.stringLen(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret i32 %s.len
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.stringIndex(ptr %s.data, i32 %s.len, i32 %index, ptr %context) unnamed_addr #2 {
|
||||
define hidden i8 @main.stringIndex(ptr %s.data, i32 %s.len, i32 %index, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%.not = icmp ult i32 %index, %s.len
|
||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||
@@ -52,19 +53,19 @@ lookup.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @runtime.lookupPanic(ptr) #1
|
||||
declare void @runtime.lookupPanic(ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.stringCompareEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.stringCompareEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #3
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
declare i1 @runtime.stringEqual(ptr, i32, ptr, i32, ptr) #1
|
||||
declare i1 @runtime.stringEqual(ptr, i32, ptr, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.stringCompareUnequal(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.stringCompareUnequal(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #3
|
||||
%1 = xor i1 %0, true
|
||||
@@ -72,16 +73,16 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i1 @main.stringCompareLarger(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #2 {
|
||||
define hidden i1 @main.stringCompareLarger(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = call i1 @runtime.stringLess(ptr %s2.data, i32 %s2.len, ptr %s1.data, i32 %s1.len, ptr undef) #3
|
||||
ret i1 %0
|
||||
}
|
||||
|
||||
declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #1
|
||||
declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #2 {
|
||||
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = zext i8 %x to i32
|
||||
%.not = icmp ult i32 %0, %s.len
|
||||
@@ -97,7 +98,7 @@ lookup.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+17
-16
@@ -8,16 +8,17 @@ target triple = "wasm32-unknown-wasi"
|
||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden i32 @main.testZeroGet(ptr dereferenceable_or_null(40) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #3 {
|
||||
define hidden i32 @main.testZeroGet(ptr dereferenceable_or_null(40) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
%hashmap.key = alloca %main.hasPadding, align 8
|
||||
%hashmap.value = alloca i32, align 4
|
||||
@@ -39,17 +40,17 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3
|
||||
|
||||
declare void @runtime.memzero(ptr, i32, ptr) #1
|
||||
declare void @runtime.memzero(ptr, i32, ptr) #4
|
||||
|
||||
declare i1 @runtime.hashmapBinaryGet(ptr dereferenceable_or_null(40), ptr, ptr, i32, ptr) #1
|
||||
declare i1 @runtime.hashmapBinaryGet(ptr dereferenceable_or_null(40), ptr, ptr, i32, ptr) #4
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #4
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden void @main.testZeroSet(ptr dereferenceable_or_null(40) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #3 {
|
||||
define hidden void @main.testZeroSet(ptr dereferenceable_or_null(40) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
%hashmap.key = alloca %main.hasPadding, align 8
|
||||
%hashmap.value = alloca i32, align 4
|
||||
@@ -70,10 +71,10 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @runtime.hashmapBinarySet(ptr dereferenceable_or_null(40), ptr, ptr, ptr) #1
|
||||
declare void @runtime.hashmapBinarySet(ptr dereferenceable_or_null(40), ptr, ptr, ptr) #4
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden i32 @main.testZeroArrayGet(ptr dereferenceable_or_null(40) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #3 {
|
||||
define hidden i32 @main.testZeroArrayGet(ptr dereferenceable_or_null(40) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
%hashmap.key = alloca [2 x %main.hasPadding], align 8
|
||||
%hashmap.value = alloca i32, align 4
|
||||
@@ -100,7 +101,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden void @main.testZeroArraySet(ptr dereferenceable_or_null(40) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #3 {
|
||||
define hidden void @main.testZeroArraySet(ptr dereferenceable_or_null(40) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
%hashmap.key = alloca [2 x %main.hasPadding], align 8
|
||||
%hashmap.value = alloca i32, align 4
|
||||
@@ -127,14 +128,14 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.main(ptr %context) unnamed_addr #2 {
|
||||
define hidden void @main.main(ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #2 = { noinline nounwind "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
attributes #4 = { "target-features"="+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext" }
|
||||
attributes #5 = { nounwind }
|
||||
|
||||
@@ -19,7 +19,7 @@ require (
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/tools v0.22.1-0.20240621165957-db513b091504
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
tinygo.org/x/go-llvm v0.0.0-20240627184919-3b50c76783a8
|
||||
tinygo.org/x/go-llvm v0.0.0-20240804145059-aaff3eb751f0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -77,5 +77,5 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240627184919-3b50c76783a8 h1:bLsZXRUBavt++CJlMN7sppNziqu3LyamESLhFJcpqFQ=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240627184919-3b50c76783a8/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240804145059-aaff3eb751f0 h1:aN9rSxvVWmipB13yVAFOmRj3LX4Kkfiq/fSl5EAilDA=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240804145059-aaff3eb751f0/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
|
||||
+10
-2
@@ -286,10 +286,18 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
runTest("rand.go", options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
if !isWebAssembly {
|
||||
// The recover() builtin isn't supported yet on WebAssembly and Windows.
|
||||
if !isWASI {
|
||||
// On WebAssembly, recover() needs the exception handling proposal which
|
||||
// isn't (as of 2024) implemented in wasmtime so this test is skipped on
|
||||
// WASI.
|
||||
t.Run("recover.go", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := options
|
||||
if isWebAssembly {
|
||||
// Hack: Asyncify doesn't support exception handling
|
||||
// instructions.
|
||||
options.Scheduler = "none"
|
||||
}
|
||||
runTest("recover.go", options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
|
||||
+98
-28
@@ -15,11 +15,20 @@ func trap()
|
||||
// purposes of TinyGo. It restores the stack pointer and jumps to the given pc.
|
||||
//
|
||||
//export tinygo_longjmp
|
||||
func tinygo_longjmp(frame *deferFrame)
|
||||
func tinygo_longjmp(frame *deferFrameInlineAsm)
|
||||
|
||||
// Compiler intrinsic.
|
||||
// Returns whether recover is supported on the current architecture.
|
||||
func supportsRecover() bool
|
||||
func supportsRecover() recoverType
|
||||
|
||||
type recoverType uint8
|
||||
|
||||
const (
|
||||
// Note: these contants match recoverSupport in compiler/defer.go
|
||||
recoverNone recoverType = iota
|
||||
recoverInlineAsm
|
||||
recoverWasmEH
|
||||
)
|
||||
|
||||
const (
|
||||
panicStrategyPrint = 1
|
||||
@@ -31,33 +40,55 @@ const (
|
||||
// using the -panic= compiler flag.
|
||||
func panicStrategy() uint8
|
||||
|
||||
// DeferFrame is a stack allocated object that stores information for the
|
||||
// current "defer frame", which is used in functions that use the `defer`
|
||||
// LLVM compiler intrinsic: this inserts a wasm 'throw' instruction.
|
||||
//
|
||||
//export llvm.wasm.throw
|
||||
func wasm_throw(uint32, unsafe.Pointer)
|
||||
|
||||
// DeferFrameInlineAsm is a stack allocated object that stores information for
|
||||
// the current "defer frame", which is used in functions that use the `defer`
|
||||
// keyword.
|
||||
// The compiler knows about the JumpPC struct offset, so it should not be moved
|
||||
// without also updating compiler/defer.go.
|
||||
type deferFrame struct {
|
||||
type deferFrameInlineAsm struct {
|
||||
JumpSP unsafe.Pointer // stack pointer to return to
|
||||
JumpPC unsafe.Pointer // pc to return to
|
||||
ExtraRegs [deferExtraRegs]unsafe.Pointer // extra registers (depending on the architecture)
|
||||
Previous *deferFrame // previous recover buffer pointer
|
||||
Previous *deferFrameInlineAsm // previous recover buffer pointer
|
||||
Panicking bool // true iff this defer frame is panicking
|
||||
PanicValue interface{} // panic value, might be nil for panic(nil) for example
|
||||
}
|
||||
|
||||
// DeferFrameWasmEH is like deferFrameInlineAsm but for WebAssembly exception
|
||||
// handling.
|
||||
type deferFrameWasmEH struct {
|
||||
Previous *deferFrameWasmEH // previous recover buffer pointer
|
||||
Panicking bool // true iff this defer frame is panicking
|
||||
PanicValue interface{} // panic value, might be nil for panic(nil) for example
|
||||
}
|
||||
|
||||
// Builtin function panic(msg), used as a compiler intrinsic.
|
||||
func _panic(message interface{}) {
|
||||
if panicStrategy() == panicStrategyTrap {
|
||||
trap()
|
||||
}
|
||||
if supportsRecover() {
|
||||
frame := (*deferFrame)(task.Current().DeferFrame)
|
||||
switch supportsRecover() {
|
||||
case recoverInlineAsm:
|
||||
frame := (*deferFrameInlineAsm)(task.Current().DeferFrame)
|
||||
if frame != nil {
|
||||
frame.PanicValue = message
|
||||
frame.Panicking = true
|
||||
tinygo_longjmp(frame)
|
||||
// unreachable
|
||||
}
|
||||
case recoverWasmEH:
|
||||
frame := (*deferFrameWasmEH)(task.Current().DeferFrame)
|
||||
if frame != nil {
|
||||
frame.PanicValue = message
|
||||
frame.Panicking = true
|
||||
wasm_throw(0, nil)
|
||||
// unreachable
|
||||
}
|
||||
}
|
||||
printstring("panic: ")
|
||||
printitf(message)
|
||||
@@ -94,21 +125,43 @@ func runtimePanicAt(addr unsafe.Pointer, msg string) {
|
||||
//
|
||||
//go:inline
|
||||
//go:nobounds
|
||||
func setupDeferFrame(frame *deferFrame, jumpSP unsafe.Pointer) {
|
||||
func setupDeferFrameInlineAsm(frame *deferFrameInlineAsm, jumpSP unsafe.Pointer) {
|
||||
currentTask := task.Current()
|
||||
frame.Previous = (*deferFrame)(currentTask.DeferFrame)
|
||||
frame.Previous = (*deferFrameInlineAsm)(currentTask.DeferFrame)
|
||||
frame.JumpSP = jumpSP
|
||||
frame.Panicking = false
|
||||
currentTask.DeferFrame = unsafe.Pointer(frame)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
//go:nobounds
|
||||
func setupDeferFrameWasmEH(frame *deferFrameWasmEH) {
|
||||
currentTask := task.Current()
|
||||
frame.Previous = (*deferFrameWasmEH)(currentTask.DeferFrame)
|
||||
frame.Panicking = false
|
||||
currentTask.DeferFrame = unsafe.Pointer(frame)
|
||||
}
|
||||
|
||||
// Called right before the return instruction. It pops the defer frame from the
|
||||
// linked list of defer frames. It also re-raises a panic if the goroutine is
|
||||
// still panicking.
|
||||
//
|
||||
//go:inline
|
||||
//go:nobounds
|
||||
func destroyDeferFrame(frame *deferFrame) {
|
||||
func destroyDeferFrameInlineAsm(frame *deferFrameInlineAsm) {
|
||||
task.Current().DeferFrame = unsafe.Pointer(frame.Previous)
|
||||
if frame.Panicking {
|
||||
// We're still panicking!
|
||||
// Re-raise the panic now.
|
||||
_panic(frame.PanicValue)
|
||||
}
|
||||
}
|
||||
|
||||
// Like destroyDeferFrameInlineAsm but for wasm.
|
||||
//
|
||||
//go:inline
|
||||
//go:nobounds
|
||||
func destroyDeferFrameWasmEH(frame *deferFrameWasmEH) {
|
||||
task.Current().DeferFrame = unsafe.Pointer(frame.Previous)
|
||||
if frame.Panicking {
|
||||
// We're still panicking!
|
||||
@@ -122,27 +175,44 @@ func destroyDeferFrame(frame *deferFrame) {
|
||||
// useParentFrame is set when the caller of runtime._recover has a defer frame
|
||||
// itself. In that case, recover() shouldn't check that frame but one frame up.
|
||||
func _recover(useParentFrame bool) interface{} {
|
||||
if !supportsRecover() {
|
||||
// Compiling without stack unwinding support, so make this a no-op.
|
||||
return nil
|
||||
}
|
||||
// TODO: somehow check that recover() is called directly by a deferred
|
||||
// function in a panicking goroutine. Maybe this can be done by comparing
|
||||
// the frame pointer?
|
||||
frame := (*deferFrame)(task.Current().DeferFrame)
|
||||
if useParentFrame {
|
||||
// Don't recover panic from the current frame (which can't be panicking
|
||||
// already), but instead from the previous frame.
|
||||
frame = frame.Previous
|
||||
switch supportsRecover() {
|
||||
case recoverInlineAsm:
|
||||
frame := (*deferFrameInlineAsm)(task.Current().DeferFrame)
|
||||
if useParentFrame {
|
||||
// Don't recover panic from the current frame (which can't be
|
||||
// panicking already), but instead from the previous frame.
|
||||
frame = frame.Previous
|
||||
}
|
||||
if frame != nil && frame.Panicking {
|
||||
// Only the first call to recover returns the panic value. It also
|
||||
// stops the panicking sequence, hence setting panicking to false.
|
||||
frame.Panicking = false
|
||||
return frame.PanicValue
|
||||
}
|
||||
// Not panicking, so return a nil interface.
|
||||
return nil
|
||||
case recoverWasmEH:
|
||||
frame := (*deferFrameWasmEH)(task.Current().DeferFrame)
|
||||
if useParentFrame {
|
||||
// Don't recover panic from the current frame (which can't be
|
||||
// panicking already), but instead from the previous frame.
|
||||
frame = frame.Previous
|
||||
}
|
||||
if frame != nil && frame.Panicking {
|
||||
// Only the first call to recover returns the panic value. It also
|
||||
// stops the panicking sequence, hence setting panicking to false.
|
||||
frame.Panicking = false
|
||||
return frame.PanicValue
|
||||
}
|
||||
// Not panicking, so return a nil interface.
|
||||
return nil
|
||||
default:
|
||||
// Compiling without stack unwinding support, so make this a no-op.
|
||||
return nil
|
||||
}
|
||||
if frame != nil && frame.Panicking {
|
||||
// Only the first call to recover returns the panic value. It also stops
|
||||
// the panicking sequence, hence setting panicking to false.
|
||||
frame.Panicking = false
|
||||
return frame.PanicValue
|
||||
}
|
||||
// Not panicking, so return a nil interface.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Panic when trying to dereference a nil pointer.
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"llvm-target": "wasm32-unknown-wasi",
|
||||
"cpu": "generic",
|
||||
"features": "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext",
|
||||
"features": "+bulk-memory,+exception-handling,+mutable-globals,+nontrapping-fptoint,+sign-ext",
|
||||
"build-tags": ["tinygo.wasm"],
|
||||
"goos": "js",
|
||||
"goarch": "wasm",
|
||||
@@ -12,6 +12,7 @@
|
||||
"default-stack-size": 65536,
|
||||
"cflags": [
|
||||
"-mbulk-memory",
|
||||
"-mexception-handling",
|
||||
"-mnontrapping-fptoint",
|
||||
"-msign-ext"
|
||||
],
|
||||
|
||||
Vendored
+27
@@ -17,6 +17,12 @@ func main() {
|
||||
println("\n# panic inside defer")
|
||||
panicInsideDefer()
|
||||
|
||||
println("\n# panic inside indirect defer")
|
||||
panicInsideIndirectDefer(callPanic)
|
||||
|
||||
println("\n# panic inside closure")
|
||||
panicInsideClosure()
|
||||
|
||||
println("\n# panic replace")
|
||||
panicReplace()
|
||||
}
|
||||
@@ -77,6 +83,27 @@ func panicInsideDefer() {
|
||||
}()
|
||||
}
|
||||
|
||||
func panicInsideIndirectDefer(callback func()) {
|
||||
defer func() {
|
||||
printitf("recovered:", recover())
|
||||
}()
|
||||
defer callback()
|
||||
}
|
||||
|
||||
func callPanic() {
|
||||
panic("panic")
|
||||
}
|
||||
|
||||
func panicInsideClosure() {
|
||||
msg := "panic"
|
||||
defer func() {
|
||||
printitf("recovered:", recover())
|
||||
}()
|
||||
defer func() {
|
||||
panic(msg)
|
||||
}()
|
||||
}
|
||||
|
||||
func panicReplace() {
|
||||
defer func() {
|
||||
printitf("recovered:", recover())
|
||||
|
||||
Vendored
+6
@@ -19,6 +19,12 @@ recovered 2: foo
|
||||
# panic inside defer
|
||||
recovered: panic
|
||||
|
||||
# panic inside indirect defer
|
||||
recovered: panic
|
||||
|
||||
# panic inside closure
|
||||
recovered: panic
|
||||
|
||||
# panic replace
|
||||
panic 1
|
||||
panic 2
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
|
||||
// now.
|
||||
// With more analysis, it should be possible to optimize a
|
||||
// significant chunk of these away.
|
||||
case llvm.Call, llvm.Load, llvm.IntToPtr:
|
||||
case llvm.Call, llvm.Invoke, llvm.Load, llvm.IntToPtr:
|
||||
// These create new values so must be stored locally. But
|
||||
// perhaps some of these can be fused when they actually refer
|
||||
// to the same value.
|
||||
|
||||
Reference in New Issue
Block a user