// File: /workspace/github_cpp_makefile_star2_O2/Alcaro[P]bridges/arlib/json.cpp
// Function: jsonparser::next()
jsonparser::event jsonparser::next()
{
	uint8_t ch = nextch();
	if (m_want_key)
	{
		m_want_key = false;
		if (ch == '"') goto parse_key;
		else if (ch == '}') goto close_brace;
		else return do_error();
	}
	
	if (ch == '\0')
	{
		if (m_need_value)
		{
			m_need_value = false;
			return do_error();
		}
		if (m_nesting)
		{
			if (!m_unexpected_end)
			{
				m_unexpected_end = true;
				return do_error();
			}
			bool map = (m_nesting[m_nesting.size()-1] == true);
			m_nesting.resize(m_nesting.size()-1);
			return { map ? exit_map : exit_list };
		}
		return { finish };
	}
	if (m_need_value && (ch == ']' || ch == '}'))
	{
		m_need_value = false;
		m_data--;
		return do_error();
	}
	m_need_value = false;
	
	if (ch == '"')
	{
		bool is_key;
		is_key = false;
		if (false)
		{
		parse_key:
			is_key = true;
		}
		uint8_t * val_out_start = m_data;
		uint8_t * val_out = m_data;
		
		//most strings don't contain escapes, special case them
		uint8_t * fast_iter = m_data;
#ifdef __SSE2__
		while (fast_iter+16 <= m_data_end)
		{
			__m128i chs = _mm_loadu_si128((__m128i*)fast_iter);
			
			// xor 128 because signed compare; xor 2 to fold " to beside the control chars and not check it separately
			__m128i bad1 = _mm_cmplt_epi8(_mm_xor_si128(chs, _mm_set1_epi8(0x82)), _mm_set1_epi8((int8_t)(0x21^0x80)));
			__m128i bad2 = _mm_cmpeq_epi8(chs, _mm_set1_epi8(0x5C)); // can't find any way to optimize out the \ check
			__m128i bad = _mm_or_si128(bad1, bad2);
			int mask = _mm_movemask_epi8(bad); // always in uint16 range, but gcc doesn't know that; keeping it as int optimizes better
			if (mask == 0)
			{
				fast_iter += 16;
				continue;
			}
			fast_iter += ctz32(mask);
			val_out = fast_iter;
			m_data = fast_iter;
			if (LIKELY(*m_data == '"'))
			{
				m_data++;
				goto skip_escape_parse;
			}
			break;
		}
		//just take the slow path for the last 16 bytes of the document
#else
		while (true)
		{
			uint8_t ch = *fast_iter;
			if (UNLIKELY((ch^2) <= 32 || ch == '\\'))
			{
				val_out = fast_iter;
				m_data = fast_iter;
				if (LIKELY(ch == '"'))
				{
					m_data++;
					goto skip_escape_parse;
				}
				break;
			}
			fast_iter++;
		}
#endif
		
		while (true)
		{
			uint8_t ch = *(m_data++);
			if (ch == '\\')
			{
				uint8_t esc = *(m_data++);
				switch (esc)
				{
				case '"': *val_out++ =  '"'; break;
				case '\\':*val_out++ = '\\'; break;
				case '/': *val_out++ =  '/'; break;
				case 'b': *val_out++ = '\b'; break;
				case 'f': *val_out++ = '\f'; break;
				case 'n': *val_out++ = '\n'; break;
				case 'r': *val_out++ = '\r'; break;
				case 't': *val_out++ = '\t'; break;
				case 'u':
				{
					if (UNLIKELY(m_data+4 > m_data_end)) return do_error();
					
					uint32_t codepoint;
					if (UNLIKELY(!fromstringhex(arrayview<uint8_t>(m_data, 4), codepoint))) return do_error();
					m_data += 4;
					
					// curse utf16 forever
					if (codepoint >= 0xD800 && codepoint <= 0xDBFF && m_data[0] == '\\' && m_data[1] == 'u')
					{
						uint16_t low_sur;
						if (UNLIKELY(!fromstringhex(arrayview<uint8_t>(m_data+2, 4), low_sur))) return do_error();
						
						if (low_sur >= 0xDC00 && low_sur <= 0xDFFF)
						{
							m_data += 6;
							codepoint = 0x10000 + ((codepoint-0xD800)<<10) + (low_sur-0xDC00);
						}
					}
					// else leave as is, string::codepoint will return fffd for unpaired surrogates
					
					val_out += string::codepoint(val_out, codepoint);
					break;
				}
				default:
					m_data--;
					return do_error();
				}
				continue;
			}
			if (ch == '"') break;
			if (ch < 32)
			{
				m_data--;
				return do_error();
			}
			*val_out++ = ch;
		}
	skip_escape_parse:
		*val_out = '\0';
		cstring val(arrayview<uint8_t>(val_out_start, val_out-val_out_start), true);
		if (is_key)
		{
			if (nextch() != ':') return do_error();
			return { map_key, val };
		}
		else
		{
			if (!skipcomma()) return do_error();
			return { str, val };
		}
	}
	if (ch == '[')
	{
		m_nesting.append(false);
		return { enter_list };
	}
	if (ch == ']')
	{
		if (!m_nesting || m_nesting[m_nesting.size()-1] != false) return do_error();
		if (!skipcomma(2)) return do_error();
		m_nesting.resize(m_nesting.size()-1);
		return { exit_list };
	}
	if (ch == '{')
	{
		m_nesting.append(true);
		m_want_key = true;
		return { enter_map };
	}
	if (ch == '}')
	{
	close_brace:
		m_want_key = false;
		if (!m_nesting || m_nesting[m_nesting.size()-1] != true) return do_error();
		if (!skipcomma(2)) return do_error();
		m_nesting.resize(m_nesting.size()-1);
		return { exit_map };
	}
	if (ch == '-' || isdigit(ch))
	{
		m_data--;
		const uint8_t * start = m_data;
		if (*m_data == '-') m_data++;
		if (*m_data == '0') m_data++;
		else
		{
			if (!isdigit(*m_data)) return do_error();
			while (isdigit(*m_data)) m_data++;
		}
		if (*m_data == '.')
		{
			m_data++;
			if (!isdigit(*m_data)) return do_error();
			while (isdigit(*m_data)) m_data++;
		}
		if (*m_data == 'e' || *m_data == 'E')
		{
			m_data++;
			if (*m_data == '+' || *m_data == '-') m_data++;
			if (!isdigit(*m_data)) return do_error();
			while (isdigit(*m_data)) m_data++;
		}
		
		size_t len = m_data-start;
		if (!skipcomma()) return do_error();
		return { num, arrayview<uint8_t>(start, len) };
	}
	if (ch == 't' && m_data+3 <= m_data_end && readu_le32(m_data-1) == 0x65757274) // true
	{
		m_data += 3;
		if (!skipcomma()) return do_error();
		return { jtrue };
	}
	if (ch == 'f' && m_data+4 <= m_data_end && readu_le32(m_data) == 0x65736c61) // alse
	{
		m_data += 4;
		if (!skipcomma()) return do_error();
		return { jfalse };
	}
	if (ch == 'n' && m_data+3 <= m_data_end && readu_le32(m_data-1) == 0x6c6c756e) // null
	{
		m_data += 3;
		if (!skipcomma()) return do_error();
		return { jnull };
	}
	
	return do_error();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0xf704
movb 0x20(%r14), %r13b
movzbl %al, %ecx
cmpb $0x1, %r13b
jne 0xf844
movb $0x0, 0x20(%r14)
cmpb $0x22, %al
je 0xf8ca
cmpl $0x7d, %ecx
jne 0xfb8e
movb $0x0, 0x20(%r14)
movq 0x30(%r14), %rax
testq %rax, %rax
je 0xfb8e
leaq 0x28(%r14), %r15
decq %rax
leaq 0x8(%rsp), %rdi
movq %r15, (%rdi)
movq %rax, 0x8(%rdi)
callq 0x5624
testb %al, %al
je 0xfb8e
pushq $0x2
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
movq 0x30(%r14), %rsi
decq %rsi
movq %r15, %rdi
callq 0x4498
movl $0xa, (%rbx)
jmp 0xfb99
movb 0x21(%r14), %dl
testb %al, %al
je 0xf870
xorb $0x1, %dl
movl %eax, %esi
andb $-0x21, %sil
cmpb $0x5d, %sil
setne %sil
movb $0x0, 0x21(%r14)
orb %dl, %sil
jne 0xf895
decq 0x10(%r14)
jmp 0xfb8e
testb %dl, %dl
je 0xfb19
xorl %eax, %eax
movb %al, 0x21(%r14)
movb $0x1, 0x23(%r14)
movl $0xb, (%rbx)
movb $0xf, 0x17(%rbx)
movb %al, 0x8(%rbx)
jmp 0xfba1
cmpb $0x7d, %al
je 0xf7e5
cmpl $0x2d, %ecx
je 0xfcb1
cmpl $0x5b, %ecx
je 0xfbc4
cmpl $0x5d, %ecx
je 0xfbf3
cmpl $0x7b, %ecx
je 0xfbda
cmpl $0x22, %ecx
jne 0xfc49
movq 0x10(%r14), %r15
movq 0x18(%r14), %rax
leaq -0x10(%r15), %rcx
movdqa 0x190a2(%rip), %xmm0    # 0x28980
movdqa 0x190aa(%rip), %xmm1    # 0x28990
movdqa 0x190b2(%rip), %xmm2    # 0x289a0
leaq 0x20(%rcx), %rdx
cmpq %rax, %rdx
ja 0xf981
movdqu 0x10(%rcx), %xmm3
addq $0x10, %rcx
movdqa %xmm3, %xmm4
pxor %xmm0, %xmm4
movdqa %xmm1, %xmm5
pcmpgtb %xmm4, %xmm5
pcmpeqb %xmm2, %xmm3
por %xmm5, %xmm3
pmovmskb %xmm3, %edx
testl %edx, %edx
je 0xf8ee
bsfl %edx, %edx
leaq (%rcx,%rdx), %rax
movq %rax, 0x10(%r14)
cmpb $0x22, (%rcx,%rdx)
jne 0xf984
addq %rdx, %rcx
incq %rcx
movq %rcx, 0x10(%r14)
movq %rax, %r12
movb $0x0, (%r12)
subq %r15, %r12
leaq 0x8(%rsp), %rdi
pushq $0x1
popq %rcx
movq %r15, %rsi
movq %r12, %rdx
callq 0x42f8
testb %r13b, %r13b
je 0xfb68
movq %r14, %rdi
callq 0xf704
cmpb $0x3a, %al
jne 0xfb8e
movl $0x9, (%rbx)
jmp 0xfb7d
movq %r15, %rax
leaq 0x19035(%rip), %rbp     # 0x289c0
movq %rax, %r12
leaq 0x1(%rax), %rcx
movq %rcx, 0x10(%r14)
movzbl (%rax), %edx
cmpl $0x5c, %edx
je 0xf9b9
cmpl $0x22, %edx
je 0xf942
cmpb $0x1f, %dl
jbe 0xfb8a
movb %dl, (%r12)
incq %r12
movq 0x10(%r14), %rax
jmp 0xf98e
leaq 0x2(%rax), %rsi
movq %rsi, 0x10(%r14)
movzbl 0x1(%rax), %edx
leal -0x6e(%rdx), %edi
cmpl $0x7, %edi
jbe 0xfa01
cmpl $0x66, %edx
je 0xfaf1
cmpl $0x2f, %edx
je 0xfb05
cmpl $0x5c, %edx
je 0xfafb
cmpl $0x62, %edx
je 0xfb0f
cmpl $0x22, %edx
jne 0xfdf4
movb $0x22, (%r12)
jmp 0xf9b0
movslq (%rbp,%rdi,4), %rdx
addq %rbp, %rdx
jmpq *%rdx
movb $0xa, (%r12)
jmp 0xf9b0
movb $0xd, (%r12)
jmp 0xf9b0
addq $0x6, %rax
cmpq 0x18(%r14), %rax
ja 0xfb8e
leaq 0x28(%rsp), %rdi
pushq $0x4
popq %rdx
callq 0x1045e
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x168f2
testb %al, %al
je 0xfb8e
movq 0x10(%r14), %rax
leaq 0x4(%rax), %rcx
movq %rcx, 0x10(%r14)
movl 0x8(%rsp), %esi
movl %esi, %edx
andl $0xfffffc00, %edx       # imm = 0xFFFFFC00
cmpl $0xd800, %edx           # imm = 0xD800
jne 0xfad7
cmpb $0x5c, (%rcx)
jne 0xfad7
cmpb $0x75, 0x5(%rax)
jne 0xfad7
addq $0x6, %rax
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
pushq $0x4
popq %rdx
callq 0x1045e
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
leaq 0x6(%rsp), %rdx
callq 0x168de
testb %al, %al
je 0xfb8e
movzwl 0x6(%rsp), %eax
movl %eax, %ecx
andl $0xfc00, %ecx           # imm = 0xFC00
movl 0x8(%rsp), %esi
cmpw $0xdc00, %cx            # imm = 0xDC00
jne 0xfad7
addq $0x6, 0x10(%r14)
shll $0xa, %esi
addl %eax, %esi
addl $0xfca02400, %esi       # imm = 0xFCA02400
movl %esi, 0x8(%rsp)
movq %r12, %rdi
callq 0x15a1a
addq %rax, %r12
jmp 0xf9b3
movb $0x9, (%r12)
jmp 0xf9b0
movb $0xc, (%r12)
jmp 0xf9b0
movb $0x5c, (%r12)
jmp 0xf9b0
movb $0x2f, (%r12)
jmp 0xf9b0
movb $0x8, (%r12)
jmp 0xf9b0
movq 0x30(%r14), %rax
testq %rax, %rax
je 0xfbb3
cmpb $0x0, 0x22(%r14)
je 0xfbbb
leaq 0x28(%r14), %r15
decq %rax
leaq 0x8(%rsp), %rdi
movq %r15, (%rdi)
movq %rax, 0x8(%rdi)
callq 0x5624
movl %eax, %ebp
movq 0x30(%r14), %rsi
decq %rsi
movq %r15, %rdi
callq 0x4498
movzbl %bpl, %eax
leal (%rax,%rax,2), %eax
addl $0x7, %eax
movl %eax, (%rbx)
jmp 0xfb99
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
movl $0x4, (%rbx)
movdqu 0x8(%rsp), %xmm0
movdqu %xmm0, 0x8(%rbx)
jmp 0xfba1
movq %rax, 0x10(%r14)
movb $0x1, 0x23(%r14)
movl $0xb, (%rbx)
movb $0xf, 0x17(%rbx)
movb $0x0, 0x8(%rbx)
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0xc, (%rbx)
jmp 0xfb99
movw $0x101, 0x22(%r14)      # imm = 0x101
jmp 0xfb93
addq $0x28, %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x10466
movl $0x6, (%rbx)
jmp 0xfb99
leaq 0x28(%r14), %rdi
pushq $0x1
popq %rsi
callq 0x10466
movb $0x1, 0x20(%r14)
movl $0x8, (%rbx)
jmp 0xfb99
movq 0x30(%r14), %rax
testq %rax, %rax
je 0xfb8e
leaq 0x28(%r14), %r15
decq %rax
leaq 0x8(%rsp), %rdi
movq %r15, (%rdi)
movq %rax, 0x8(%rdi)
callq 0x5624
testb %al, %al
jne 0xfb8e
pushq $0x2
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
movq 0x30(%r14), %rsi
decq %rsi
movq %r15, %rdi
callq 0x4498
movl $0x7, (%rbx)
jmp 0xfb99
leaq 0x19040(%rip), %rdx     # 0x28c90
testb $0x40, (%rdx,%rcx)
jne 0xfcb1
cmpb $0x66, %al
je 0xfe3e
cmpl $0x6e, %ecx
je 0xfdfd
cmpl $0x74, %ecx
jne 0xfb8e
movq 0x10(%r14), %rcx
leaq 0x3(%rcx), %rax
cmpq 0x18(%r14), %rax
ja 0xfb8e
cmpl $0x65757274, -0x1(%rcx) # imm = 0x65757274
jne 0xfb8e
movq %rax, 0x10(%r14)
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
movl $0x1, (%rbx)
jmp 0xfb99
movq 0x10(%r14), %rax
leaq -0x1(%rax), %r15
movq %r15, 0x10(%r14)
xorl %edx, %edx
cmpb $0x2d, -0x1(%rax)
setne %dl
movq %r15, %rcx
cmoveq %rax, %rcx
movq %rcx, 0x10(%r14)
negq %rdx
movzbl (%rax,%rdx), %eax
cmpq $0x30, %rax
jne 0xfceb
leaq 0x1(%rcx), %r12
movq %r12, 0x10(%r14)
movb 0x1(%rcx), %al
jmp 0xfd1c
leaq 0x18f9e(%rip), %rdx     # 0x28c90
movb (%rdx,%rax), %sil
testb $0x40, %sil
je 0xfb8e
incq %rcx
testb $0x40, %sil
je 0xfd16
movq %rcx, 0x10(%r14)
movzbl (%rcx), %eax
movb (%rdx,%rax), %sil
jmp 0xfd00
decq %rcx
movq %rcx, %r12
cmpb $0x2e, %al
jne 0xfd5f
leaq 0x1(%r12), %rax
movq %rax, 0x10(%r14)
movzbl 0x1(%r12), %eax
leaq 0x18f5a(%rip), %rcx     # 0x28c90
movb (%rcx,%rax), %dl
testb $0x40, %dl
je 0xfb8e
addq $0x2, %r12
testb $0x40, %dl
je 0xfd5c
movq %r12, 0x10(%r14)
movzbl (%r12), %eax
movb (%rcx,%rax), %dl
incq %r12
jmp 0xfd46
decq %r12
movzbl %al, %eax
orl $0x20, %eax
cmpl $0x65, %eax
jne 0xfdc1
leaq 0x1(%r12), %rax
movq %rax, 0x10(%r14)
movzbl 0x1(%r12), %ecx
cmpl $0x2d, %ecx
je 0xfd83
cmpl $0x2b, %ecx
jne 0xfd91
leaq 0x2(%r12), %rax
movq %rax, 0x10(%r14)
movb 0x2(%r12), %cl
movzbl %cl, %edx
leaq 0x18ef5(%rip), %rcx     # 0x28c90
movb (%rcx,%rdx), %dl
testb $0x40, %dl
je 0xfb8e
incq %rax
testb $0x40, %dl
je 0xfdbb
movq %rax, 0x10(%r14)
movzbl (%rax), %edx
movb (%rcx,%rdx), %dl
jmp 0xfda7
decq %rax
movq %rax, %r12
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
subq %r15, %r12
movl $0x5, (%rbx)
movq %rbx, %rdi
addq $0x8, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x1045e
jmp 0xfba1
movq %rcx, 0x10(%r14)
jmp 0xfb8e
movq 0x10(%r14), %rcx
leaq 0x3(%rcx), %rax
cmpq 0x18(%r14), %rax
ja 0xfb8e
cmpl $0x6c6c756e, -0x1(%rcx) # imm = 0x6C6C756E
jne 0xfb8e
movq %rax, 0x10(%r14)
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
movl $0x3, (%rbx)
jmp 0xfb99
movq 0x10(%r14), %rcx
leaq 0x4(%rcx), %rax
cmpq 0x18(%r14), %rax
ja 0xfb8e
cmpl $0x65736c61, (%rcx)     # imm = 0x65736C61
jne 0xfb8e
movq %rax, 0x10(%r14)
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0xf73a
testb %al, %al
je 0xfb8e
movl $0x2, (%rbx)
jmp 0xfb99