mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 13:03:39 +00:00
compiler: share recoverable fault blocks
This commit is contained in:
+18
-9
@@ -828,18 +828,10 @@ func (b *builder) createTypeAssert(expr *ssa.TypeAssert) llvm.Value {
|
||||
return tuple
|
||||
} else {
|
||||
// Type assert without comma-ok. If it fails, panic.
|
||||
faultBlock := b.ctx.AddBasicBlock(b.llvmFn, "typeassert.throw")
|
||||
faultBlock := b.getInterfaceAssertBlock()
|
||||
b.currentBlockInfo.exit = okBlock
|
||||
b.CreateCondBr(commaOk, okBlock, faultBlock)
|
||||
|
||||
// Fault: emit a checkpoint (for recover) and panic.
|
||||
b.SetInsertPointAtEnd(faultBlock)
|
||||
if b.hasDeferFrame() {
|
||||
b.createFaultCheckpoint()
|
||||
}
|
||||
b.createRuntimeCall("interfaceTypeAssert", []llvm.Value{llvm.ConstInt(b.ctx.Int1Type(), 0, false)}, "")
|
||||
b.CreateUnreachable()
|
||||
|
||||
// OK: extract the value from the interface.
|
||||
b.SetInsertPointAtEnd(okBlock)
|
||||
if _, ok := expr.AssertedType.Underlying().(*types.Interface); ok {
|
||||
@@ -849,6 +841,23 @@ func (b *builder) createTypeAssert(expr *ssa.TypeAssert) llvm.Value {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *builder) getInterfaceAssertBlock() llvm.BasicBlock {
|
||||
if !b.interfaceAssertBlock.IsNil() {
|
||||
return b.interfaceAssertBlock
|
||||
}
|
||||
savedBlock := b.GetInsertBlock()
|
||||
block := b.ctx.AddBasicBlock(b.llvmFn, "typeassert.throw")
|
||||
b.interfaceAssertBlock = block
|
||||
b.SetInsertPointAtEnd(block)
|
||||
if b.hasDeferFrame() {
|
||||
b.createFaultCheckpoint()
|
||||
}
|
||||
b.createRuntimeCall("interfaceTypeAssert", []llvm.Value{llvm.ConstInt(b.ctx.Int1Type(), 0, false)}, "")
|
||||
b.CreateUnreachable()
|
||||
b.SetInsertPointAtEnd(savedBlock)
|
||||
return block
|
||||
}
|
||||
|
||||
// getMethodsString returns a string to be used in the "tinygo-methods" string
|
||||
// attribute for interface functions.
|
||||
func (c *compilerContext) getMethodsString(itf *types.Interface) string {
|
||||
|
||||
Reference in New Issue
Block a user