// File: /workspace/github_cpp_makefile_star2_O3/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 $0x48, %rsp
movq %rsi, %r14
movq %rdi, %r13
movq 0x10(%rsi), %rbx
xorl %ecx, %ecx
leaq 0x1c525(%rip), %rbp     # 0x2fd50
movq %rcx, %r15
leaq (%rbx,%rcx), %r12
incq %r12
movq %r12, 0x10(%r14)
movzbl -0x1(%r12), %eax
cmpq $0x20, %rax
ja 0x138a0
leaq 0x1(%r15), %rcx
cmpb $0x0, (%rbp,%rax)
js 0x1382b
leaq (%rbx,%rcx), %rax
cmpq 0x18(%r14), %rax
jbe 0x13efc
leaq (%rbx,%rcx), %rax
decq %rax
movq %rax, 0x10(%r14)
cmpb $0x0, 0x20(%r14)
jne 0x13f07
cmpb $0x1, 0x21(%r14)
jne 0x13fb5
xorl %eax, %eax
movb %al, 0x21(%r14)
movb $0x1, 0x23(%r14)
movl $0xb, (%r13)
movb $0xf, 0x17(%r13)
movb %al, 0x8(%r13)
jmp 0x13950
movb 0x20(%r14), %r8b
testb %r8b, %r8b
je 0x1391b
movb $0x0, 0x20(%r14)
cmpl $0x22, %eax
je 0x139c0
cmpl $0x7d, %eax
jne 0x13939
movb $0x0, 0x20(%r14)
movq 0x30(%r14), %rcx
testq %rcx, %rcx
je 0x13939
leaq 0x28(%r14), %r15
leaq -0x1(%rcx), %rax
movq %r15, %rdx
cmpq $0x41, %rcx
jb 0x138de
movq (%r15), %rdx
movq %rax, %rcx
shrq $0x3, %rcx
movzbl (%rdx,%rcx), %ecx
andl $0x7, %eax
btl %eax, %ecx
jae 0x13939
movl $0x2, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
je 0x13939
movq 0x30(%r14), %rsi
decq %rsi
movq %r15, %rdi
callq 0x5afc
movl $0xa, (%r13)
jmp 0x13946
movb 0x21(%r14), %cl
movl %eax, %edx
andb $-0x21, %dl
movb $0x0, 0x21(%r14)
cmpb $0x5d, %dl
jne 0x13962
testb %cl, %cl
je 0x13962
addq %r15, %rbx
movq %rbx, 0x10(%r14)
movb $0x1, 0x23(%r14)
movl $0xb, (%r13)
movb $0xf, 0x17(%r13)
movb $0x0, 0x8(%r13)
movq %r13, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x5c, %eax
jg 0x13ab1
cmpl $0x22, %eax
je 0x139c0
cmpl $0x2d, %eax
je 0x13d22
cmpl $0x5b, %eax
jne 0x13acc
leaq 0x28(%r14), %r15
movq 0x30(%r14), %rsi
incq %rsi
movq %r15, %rdi
callq 0x5afc
movq 0x30(%r14), %rax
leaq -0x1(%rax), %rcx
cmpq $0x41, %rax
jb 0x139a7
movq 0x28(%r14), %r15
movq %rcx, %rax
movb $-0x2, %dl
rolb %cl, %dl
shrq $0x3, %rax
andb %dl, (%r15,%rax)
movl $0x6, (%r13)
jmp 0x13946
leaq (%rbx,%r15), %rcx
addq $-0xf, %rcx
movq 0x18(%r14), %rax
movdqa 0x1c04c(%rip), %xmm0    # 0x2fa20
movdqa 0x1c054(%rip), %xmm1    # 0x2fa30
movdqa 0x1c05c(%rip), %xmm2    # 0x2fa40
movq %r13, 0x8(%rsp)
movb %r8b, 0x7(%rsp)
leaq 0x20(%rcx), %rdx
cmpq %rax, %rdx
ja 0x13b3a
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 0x139ee
bsfl %edx, %edx
leaq (%rcx,%rdx), %rax
movq %rax, 0x10(%r14)
cmpb $0x22, (%rcx,%rdx)
jne 0x13b3d
addq %rdx, %rcx
incq %rcx
movq %rcx, 0x10(%r14)
movq %rax, %r13
movb $0x0, (%r13)
subq %rbx, %r13
notq %r15
addq %r13, %r15
leaq 0x18(%rsp), %rdi
movq %r12, %rsi
movq %r15, %rdx
movl $0x1, %ecx
callq 0x5990
cmpb $0x0, 0x7(%rsp)
je 0x13cdc
movq 0x10(%r14), %rax
movq 0x8(%rsp), %r13
movq %rax, %rcx
incq %rax
movq %rax, 0x10(%r14)
movzbl (%rcx), %ecx
cmpq $0x20, %rcx
ja 0x13d00
cmpb $0x0, (%rbp,%rcx)
js 0x13a7d
cmpq 0x18(%r14), %rax
jbe 0x13939
decq %rax
movq %rax, 0x10(%r14)
jmp 0x13939
cmpl $0x5d, %eax
je 0x13d71
cmpl $0x7b, %eax
je 0x13dda
cmpl $0x7d, %eax
je 0x138bc
movzbl %al, %ecx
testb $0x40, (%rbp,%rcx)
jne 0x13d22
cmpb $0x66, %al
je 0x13f62
cmpl $0x6e, %ecx
je 0x13f1c
cmpl $0x74, %ecx
jne 0x13939
leaq (%rbx,%r15), %rax
addq $0x4, %rax
cmpq 0x18(%r14), %rax
ja 0x13939
cmpl $0x65757274, (%rbx,%r15) # imm = 0x65757274
jne 0x13939
movq %rax, 0x10(%r14)
movl $0x1, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
je 0x13939
movl $0x1, (%r13)
jmp 0x13946
movq %r12, %rax
leaq 0x1bf1c(%rip), %r9      # 0x2fa60
movq %rax, %r13
leaq 0x1(%rax), %rcx
movq %rcx, 0x10(%r14)
movzbl (%rax), %edx
cmpl $0x5c, %edx
je 0x13b76
cmpl $0x22, %edx
je 0x13a46
cmpb $0x1f, %dl
jbe 0x13d5e
movb %dl, (%r13)
incq %r13
movq 0x10(%r14), %rax
jmp 0x13b47
leaq 0x2(%rax), %rsi
movq %rsi, 0x10(%r14)
movzbl 0x1(%rax), %edx
cmpl $0x61, %edx
jg 0x13ba1
cmpl $0x22, %edx
je 0x13bc0
cmpl $0x2f, %edx
je 0x13bb9
cmpl $0x5c, %edx
jne 0x13f13
movb $0x5c, (%r13)
jmp 0x13b6d
leal -0x6e(%rdx), %edi
cmpl $0x7, %edi
ja 0x13bc7
movslq (%r9,%rdi,4), %rdx
addq %r9, %rdx
jmpq *%rdx
movb $0xa, (%r13)
jmp 0x13b6d
movb $0x2f, (%r13)
jmp 0x13b6d
movb $0x22, (%r13)
jmp 0x13b6d
cmpl $0x62, %edx
je 0x13cd2
cmpl $0x66, %edx
jne 0x13f13
movb $0xc, (%r13)
jmp 0x13b6d
addq $0x6, %rax
cmpq 0x18(%r14), %rax
ja 0x13d62
movl $0x4, %edx
leaq 0x38(%rsp), %rdi
xorl %ecx, %ecx
callq 0x5990
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x1b35f
testb %al, %al
je 0x13d62
movq 0x10(%r14), %rax
leaq 0x4(%rax), %rcx
movq %rcx, 0x10(%r14)
movl 0x18(%rsp), %esi
movl %esi, %edx
andl $0xfffffc00, %edx       # imm = 0xFFFFFC00
cmpl $0xd800, %edx           # imm = 0xD800
jne 0x13ca7
cmpb $0x5c, (%rcx)
jne 0x13ca7
cmpb $0x75, 0x5(%rax)
jne 0x13ca7
addq $0x6, %rax
movl $0x4, %edx
leaq 0x28(%rsp), %rdi
movq %rax, %rsi
xorl %ecx, %ecx
callq 0x5990
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
leaq 0x16(%rsp), %rdx
callq 0x1b2b2
testb %al, %al
je 0x13d62
movzwl 0x16(%rsp), %eax
movl %eax, %ecx
andl $0xfc00, %ecx           # imm = 0xFC00
movl 0x18(%rsp), %esi
cmpl $0xdc00, %ecx           # imm = 0xDC00
jne 0x13ca7
addq $0x6, 0x10(%r14)
shll $0xa, %esi
addl %eax, %esi
addl $0xfca02400, %esi       # imm = 0xFCA02400
movl %esi, 0x18(%rsp)
movq %r13, %rdi
callq 0x1aa54
addq %rax, %r13
leaq 0x1bda7(%rip), %r9      # 0x2fa60
jmp 0x13b70
movb $0x9, (%r13)
jmp 0x13b6d
movb $0xd, (%r13)
jmp 0x13b6d
movb $0x8, (%r13)
jmp 0x13b6d
movl $0x1, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
movq 0x8(%rsp), %r13
je 0x13939
movl $0x4, (%r13)
jmp 0x13d11
cmpl $0x3a, %ecx
jne 0x13939
movl $0x9, (%r13)
movdqu 0x18(%rsp), %xmm0
movdqu %xmm0, 0x8(%r13)
jmp 0x13950
leaq (%rbx,%r15), %rdx
movq %rdx, 0x10(%r14)
cmpb $0x2d, (%rbx,%r15)
cmovneq %rdx, %r12
movq %r12, 0x10(%r14)
movzbl (%r12), %eax
cmpq $0x30, %rax
jne 0x13dfa
movq %r13, 0x8(%rsp)
leaq 0x1(%r12), %r13
movq %r13, 0x10(%r14)
movb 0x1(%r12), %al
jmp 0x13e26
movq %rax, 0x10(%r14)
movb $0x1, 0x23(%r14)
movq 0x8(%rsp), %r13
jmp 0x1393e
movq 0x30(%r14), %rcx
testq %rcx, %rcx
je 0x13939
leaq 0x28(%r14), %r15
leaq -0x1(%rcx), %rax
movq %r15, %rdx
cmpq $0x41, %rcx
jb 0x13d92
movq (%r15), %rdx
movq %rax, %rcx
shrq $0x3, %rcx
movzbl (%rdx,%rcx), %ecx
andl $0x7, %eax
btl %eax, %ecx
jb 0x13939
movl $0x2, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
je 0x13939
movq 0x30(%r14), %rsi
decq %rsi
movq %r15, %rdi
callq 0x5afc
movl $0x7, (%r13)
jmp 0x13946
leaq 0x28(%r14), %rdi
movl $0x1, %esi
callq 0x14734
movb $0x1, 0x20(%r14)
movl $0x8, (%r13)
jmp 0x13946
testb $0x40, (%rbp,%rax)
je 0x13939
movq %r13, 0x8(%rsp)
incq %r12
movq %r12, 0x10(%r14)
movzbl (%r12), %eax
incq %r12
testb $0x40, (%rbp,%rax)
jne 0x13e0d
decq %r12
movq %r12, %r13
cmpb $0x2e, %al
jne 0x13e5c
leaq 0x1(%r13), %rax
movq %rax, 0x10(%r14)
movzbl 0x1(%r13), %eax
testb $0x40, (%rbp,%rax)
je 0x13d62
addq $0x2, %r13
movq %r13, 0x10(%r14)
movzbl (%r13), %eax
incq %r13
testb $0x40, (%rbp,%rax)
jne 0x13e46
decq %r13
movzbl %al, %eax
orl $0x20, %eax
cmpl $0x65, %eax
jne 0x13eb7
leaq 0x1(%r13), %rax
movq %rax, 0x10(%r14)
movzbl 0x1(%r13), %ecx
cmpl $0x2d, %ecx
je 0x13e7e
cmpl $0x2b, %ecx
jne 0x13e8a
leaq 0x2(%r13), %rax
movq %rax, 0x10(%r14)
movb 0x2(%r13), %cl
movzbl %cl, %ecx
testb $0x40, (%rbp,%rcx)
je 0x13d62
incq %rax
movq %rax, 0x10(%r14)
movzbl (%rax), %ecx
incq %rax
testb $0x40, (%rbp,%rcx)
jne 0x13e9b
movq %rdx, %r12
decq %rax
movq %rax, %r13
jmp 0x13eba
movq %rdx, %r12
movl $0x1, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
je 0x13d62
subq %rbx, %r13
subq %r15, %r13
movq 0x8(%rsp), %rbx
movl $0x5, (%rbx)
movq %rbx, %rdi
addq $0x8, %rdi
movq %r12, %rsi
movq %r13, %rdx
xorl %ecx, %ecx
callq 0x5990
movq %rbx, %rax
jmp 0x13953
cmpb $0x0, 0x20(%r14)
je 0x13fa9
leaq 0x20(%r14), %rax
movb $0x0, (%rax)
jmp 0x13939
movq %rcx, 0x10(%r14)
jmp 0x13d62
leaq (%rbx,%r15), %rax
addq $0x4, %rax
cmpq 0x18(%r14), %rax
ja 0x13939
cmpl $0x6c6c756e, (%rbx,%r15) # imm = 0x6C6C756E
jne 0x13939
movq %rax, 0x10(%r14)
movl $0x1, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
je 0x13939
movl $0x3, (%r13)
jmp 0x13946
leaq (%rbx,%r15), %rax
addq $0x5, %rax
cmpq 0x18(%r14), %rax
ja 0x13939
cmpl $0x65736c61, 0x1(%rbx,%r15) # imm = 0x65736C61
jne 0x13939
movq %rax, 0x10(%r14)
movl $0x1, %esi
movq %r14, %rdi
callq 0x1376e
testb %al, %al
je 0x13939
movl $0x2, (%r13)
jmp 0x13946
movb $0x0, 0x21(%r14)
movb $0x1, %al
jmp 0x13acc
movq 0x30(%r14), %rax
testq %rax, %rax
je 0x14008
cmpb $0x0, 0x22(%r14)
je 0x14015
addq $0x28, %r14
leaq -0x1(%rax), %rsi
movq %r14, %rcx
cmpq $0x41, %rax
jb 0x13fd9
movq (%r14), %rcx
movq %rsi, %rax
shrq $0x3, %rax
movzbl (%rcx,%rax), %eax
movl %esi, %ecx
andl $0x7, %ecx
xorl %ebx, %ebx
btl %ecx, %eax
setb %bl
movq %r14, %rdi
callq 0x5afc
leal (%rbx,%rbx,2), %eax
addl $0x7, %eax
movl %eax, (%r13)
jmp 0x13946
movl $0xc, (%r13)
jmp 0x13946
movw $0x101, 0x22(%r14)      # imm = 0x101
jmp 0x1393e
nop