invoke/unwindを使った場合のコード


色々調べてllcに-enable-correct-eh-supportなるオプションがあることがわかった。とりあえず、invoke/unwindを使ったbit codeをファイルに落としてllcでX86機械語に変換してみました。
こんなコードです。

; ModuleID = 'foo.bc'

define i32 @test2() {
bb:
	unwind
}

define i32 @test() {
bb:
	%0 = invoke i32 @test2()
			to label %bb1 unwind label %bb2		; <i32> [#uses=0]

bb1:		; preds = %bb
	ret i32 1

bb2:		; preds = %bb
	ret i32 3
}

これがこんなになります。


	.text
	.align	16
	.globl	_test2
	.def	 _test2;	.scl	2;	.type	32;	.endef
_test2:
Llabel1:
	subl	$12, %esp
LBB1_1:	# dounwind
	movl	_llvm.sjljeh.jblist, %eax
	testl	%eax, %eax
	je	LBB1_3	# unwinderror
LBB1_2:	# unwind
	movl	$1, 4(%esp)
	movl	%eax, (%esp)
	call	__longjmp
LBB1_3:	# unwinderror
	call	_abort


	.align	16
	.globl	_test
	.def	 _test;	.scl	2;	.type	32;	.endef
_test:
Llabel2:
	subl	$820, %esp
	movl	_llvm.sjljeh.jblist, %eax
	movl	%eax, 808(%esp)
	leal	8(%esp), %eax
	movl	%eax, _llvm.sjljeh.jblist
	movl	$0, 816(%esp)
	movl	%eax, (%esp)
	call	__setjmp
	testl	%eax, %eax
	jne	LBB2_4	# setjmp.catch
LBB2_1:	# setjmp.cont
	movl	$1, 816(%esp)
	call	_test2
LBB2_2:	# bb1
	movl	$0, 816(%esp)
	movl	808(%esp), %eax
	movl	%eax, _llvm.sjljeh.jblist
	movl	$1, %eax
	addl	$820, %esp
	ret
LBB2_3:	# bb2
	movl	808(%esp), %eax
	movl	%eax, _llvm.sjljeh.jblist
	movl	$3, %eax
	addl	$820, %esp
	ret
LBB2_4:	# setjmp.catch
	movl	816(%esp), %eax
	cmpl	$1, %eax
	je	LBB2_3	# bb2
LBB2_5:	# dounwind
	movl	808(%esp), %eax
	movl	%eax, _llvm.sjljeh.jblist
	testl	%eax, %eax
	je	LBB2_7	# unwinderror
LBB2_6:	# unwind
	movl	$1, 4(%esp)
	movl	%eax, (%esp)
	call	__longjmp
LBB2_7:	# unwinderror
	call	_abort
	.section	.data$linkoncellvm.sjljeh.jblist,"w"
	.comm	_llvm.sjljeh.jblist,4		# llvm.sjljeh.jblist
	.def	 _abort;	.scl	2;	.type	32;	.endef

うーん、コード長くなるし重そうだし、ちょっと使えないなーでもこれしかないのかな。tableを使う方法はどうもDwarf3が使えるOSじゃないとダメそう。Cygwinはどうなんだろう?だめなんだろうな。