// File: sile[P]unf/src/unf/trie/searcher.hh
// Function: UNF::Trie::NormalizationForm::compose(UNF::Trie::CharStreamForComposition&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) const
void compose(CharStreamForComposition& in, std::string& buf) const {
	in.init_skipinfo();

	const char* const beg = in.cur();
	const char* current_char_head = in.cur();
	unsigned composed_char_info = 0;
	
	unsigned node_index = root;
	unsigned retry_root_node = root;
	unsigned char retry_root_class = 0;

	for(bool first=true;;) {
	  if(Util::is_utf8_char_start_byte(in.peek())) {
	    if(node_index != root)
	      first=false;
	    current_char_head = in.cur();

	    retry_root_node = node_index;
	    retry_root_class = in.get_canonical_class();
	  }

	retry:
	  unsigned next_index = nodes[node_index].jump(in.peek());
	  if(nodes[next_index].check_char()==in.read()) {
	    // succeeded
	    node_index = next_index;
	    unsigned terminal_index = nodes[node_index].jump('\0');
	    if(nodes[terminal_index].check_char()=='\0') {
	      composed_char_info = nodes[terminal_index].value();
              
	      in.mark_as_last_valid_point();
	      if(in.eos() || retry_root_class > in.get_canonical_class())
		break;
	    }
	  } else if (first==true) {
	    // no retry if current point is a part of first starter
	    break;
	  } else if (in.next_combining_char(retry_root_class, current_char_head)==true) { 
	    // back previous code-point and retry
	    node_index = retry_root_node;
	    current_char_head = in.cur();
	    goto retry;
	  } else {
	    break;
	  }
	}  
	
	if(composed_char_info != 0) {
	  // append composed unicode-character and skipped combining-characters
	  word_append(buf, value, composed_char_info);
	  in.append_skipped_chars_to_str(buf);
	  in.reset_at_marked_point();
	} else {
	  // append one unicode-character
	  in.setCur(Util::nearest_utf8_char_start_point(beg+1));
	  in.append_read_char_to_str(buf, beg);
	}
      }

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x58(%rsp), %rdi
callq 0x5870
movq 0x58(%rsp), %rdi
callq 0x57c0
movq %rax, 0x48(%rsp)
movq 0x58(%rsp), %rdi
callq 0x57c0
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x40(%rsp)
movl $0x0, 0x3c(%rsp)
movl 0x8(%rax), %ecx
movl %ecx, 0x38(%rsp)
movl 0x8(%rax), %eax
movl %eax, 0x34(%rsp)
movb $0x0, 0x33(%rsp)
movb $0x1, 0x32(%rsp)
movq 0x58(%rsp), %rdi
callq 0x58a0
movsbl %al, %edi
callq 0x3b00
testb $0x1, %al
jne 0x55a5
jmp 0x55dd
movq 0x20(%rsp), %rcx
movl 0x38(%rsp), %eax
cmpl 0x8(%rcx), %eax
je 0x55b8
movb $0x0, 0x32(%rsp)
movq 0x58(%rsp), %rdi
callq 0x57c0
movq %rax, 0x40(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x58(%rsp), %rdi
callq 0x58f0
movb %al, 0x33(%rsp)
jmp 0x55df
movq 0x20(%rsp), %rax
movq (%rax), %rax
movl 0x38(%rsp), %ecx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x10(%rsp)
movq 0x58(%rsp), %rdi
callq 0x58a0
movq 0x10(%rsp), %rdi
movzbl %al, %esi
callq 0x3c80
movl %eax, %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x2c(%rsp)
movq (%rax), %rdi
movl 0x2c(%rsp), %eax
shlq $0x2, %rax
addq %rax, %rdi
callq 0x3cc0
movl %eax, 0x1c(%rsp)
movq 0x58(%rsp), %rdi
callq 0x5970
movb %al, %cl
movl 0x1c(%rsp), %eax
movzbl %cl, %ecx
cmpl %ecx, %eax
jne 0x56ea
movq 0x20(%rsp), %rax
movl 0x2c(%rsp), %ecx
movl %ecx, 0x38(%rsp)
movq (%rax), %rdi
movl 0x38(%rsp), %eax
shlq $0x2, %rax
addq %rax, %rdi
xorl %esi, %esi
callq 0x3c80
movl %eax, %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x28(%rsp)
movq (%rax), %rdi
movl 0x28(%rsp), %eax
shlq $0x2, %rax
addq %rax, %rdi
callq 0x3cc0
cmpl $0x0, %eax
jne 0x56e8
movq 0x20(%rsp), %rax
movq (%rax), %rdi
movl 0x28(%rsp), %eax
shlq $0x2, %rax
addq %rax, %rdi
callq 0x3cd0
movl %eax, 0x3c(%rsp)
movq 0x58(%rsp), %rdi
callq 0x59c0
movq 0x58(%rsp), %rdi
callq 0x5a00
testb $0x1, %al
jne 0x56e4
movzbl 0x33(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x58(%rsp), %rdi
callq 0x58f0
movb %al, %cl
movl 0xc(%rsp), %eax
movzbl %cl, %ecx
cmpl %ecx, %eax
jle 0x56e6
jmp 0x573d
jmp 0x56e8
jmp 0x5738
movb 0x32(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x56fa
jmp 0x573d
movq 0x58(%rsp), %rdi
movb 0x33(%rsp), %al
movq 0x40(%rsp), %rdx
movzbl %al, %esi
callq 0x5a40
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x5736
movl 0x34(%rsp), %eax
movl %eax, 0x38(%rsp)
movq 0x58(%rsp), %rdi
callq 0x57c0
movq %rax, 0x40(%rsp)
jmp 0x55df
jmp 0x573d
jmp 0x558d
cmpl $0x0, 0x3c(%rsp)
je 0x5776
movq 0x20(%rsp), %rax
movq 0x50(%rsp), %rdi
movq 0x10(%rax), %rsi
movl 0x3c(%rsp), %edx
callq 0x4030
movq 0x58(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x5b60
movq 0x58(%rsp), %rdi
callq 0x5be0
jmp 0x57ad
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
movq 0x48(%rsp), %rdi
addq $0x1, %rdi
callq 0x3a60
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x5c00
movq 0x58(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x48(%rsp), %rdx
callq 0x5c60
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)